@aceshooting/lyra-ui 28.1.0 → 28.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/components/agent-tools/commit-card/commit-card.class.d.ts +2 -2
  3. package/dist/components/agent-tools/commit-card/commit-card.class.js +7 -8
  4. package/dist/components/agent-tools/eval-dataset/eval-dataset.class.js +1 -1
  5. package/dist/components/agent-tools/schema-viewer/schema-viewer.class.js +1 -1
  6. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +4 -4
  7. package/dist/components/charts/chart/box-plot.class.d.ts +1 -1
  8. package/dist/components/charts/chart/box-plot.class.js +12 -12
  9. package/dist/components/charts/chart/chart.class.d.ts +1 -1
  10. package/dist/components/charts/chart/chart.class.js +13 -13
  11. package/dist/components/charts/chart/lite-chart.class.d.ts +1 -1
  12. package/dist/components/charts/chart/lite-chart.class.js +8 -8
  13. package/dist/components/conversation/message-feedback/message-feedback.class.js +2 -2
  14. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
  15. package/dist/components/data/data-grid/data-grid-processing.js +1 -1
  16. package/dist/components/data/gauge/gauge.class.js +1 -1
  17. package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +1 -1
  18. package/dist/components/data/graph-query-builder/graph-query-builder.class.js +2 -2
  19. package/dist/components/data/heatmap/heatmap-label-cache.js +1 -0
  20. package/dist/components/data/heatmap/heatmap.class.d.ts +2 -2
  21. package/dist/components/data/heatmap/heatmap.class.js +2 -2
  22. package/dist/components/data/stat/stat.class.d.ts +11 -9
  23. package/dist/components/data/stat/stat.class.js +4 -2
  24. package/dist/components/data/tree/tree.class.js +1 -1
  25. package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
  26. package/dist/components/forms/color-picker/color-picker.class.js +3 -3
  27. package/dist/components/forms/combobox/combobox.class.d.ts +2 -4
  28. package/dist/components/forms/combobox/combobox.class.js +1 -1
  29. package/dist/components/forms/emoji-picker/emoji-picker.class.js +5 -5
  30. package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
  31. package/dist/components/forms/select/select.class.js +4 -3
  32. package/dist/components/forms/toggle-group/toggle-group.class.js +1 -1
  33. package/dist/components/layout/command-palette/command-palette.styles.js +1 -1
  34. package/dist/components/layout/filter-bar/filter-bar.class.js +3 -3
  35. package/dist/components/layout/menu/menu.class.js +1 -1
  36. package/dist/components/layout/menubar/menubar.class.js +1 -1
  37. package/dist/components/layout/navigation-menu-item/navigation-menu-item.class.d.ts +1 -1
  38. package/dist/components/layout/navigation-menu-item/navigation-menu-item.class.js +1 -1
  39. package/dist/components/layout/page/page.class.js +1 -1
  40. package/dist/components/layout/tab-group/tab-group.class.js +1 -1
  41. package/dist/components/media/attachment-trigger/attachment-trigger.class.js +1 -1
  42. package/dist/components/media/file-input/file-input.class.js +1 -1
  43. package/dist/components/media/video-playlist/video-playlist.class.js +1 -1
  44. package/dist/components/retrieval/chunk-inspector/chunk-inspector.class.d.ts +1 -1
  45. package/dist/components/retrieval/chunk-inspector/chunk-inspector.class.js +2 -2
  46. package/dist/components/retrieval/citation-badge/citation-badge.class.js +1 -1
  47. package/dist/components/retrieval/entity-chip/entity-chip.class.js +1 -1
  48. package/dist/components/retrieval/graph/graph-canvas.js +1 -1
  49. package/dist/components/retrieval/graph-legend/graph-legend.class.js +2 -2
  50. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +1 -1
  51. package/dist/components/retrieval/neighbor-list/neighbor-list.class.js +1 -1
  52. package/dist/components/retrieval/retrieval-results/retrieval-results.class.d.ts +1 -1
  53. package/dist/components/retrieval/retrieval-results/retrieval-results.class.js +4 -4
  54. package/dist/components/retrieval/source-picker/source-picker.class.d.ts +1 -1
  55. package/dist/components/retrieval/source-picker/source-picker.class.js +1 -1
  56. package/dist/components/viewers/email-viewer/email-viewer.class.js +1 -1
  57. package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +1 -1
  58. package/dist/internal/native-modal-carrier.js +2 -2
  59. package/dist/internal/overlay-manager.d.ts +2 -0
  60. package/dist/internal/overlay-manager.js +1 -1
  61. package/dist/internal/package-metadata.js +1 -1
  62. package/llms/components/lr-color-picker.md +2 -0
  63. package/llms/components/lr-commit-card.md +3 -2
  64. package/llms/components/lr-select.md +2 -0
  65. package/llms/components/lr-stat.md +4 -0
  66. package/llms/peers.md +1 -1
  67. package/llms/shared/ai-and-peers.md +44 -0
  68. package/llms/shared.md +44 -0
  69. package/package.json +5 -5
  70. package/registrations.json +1 -1
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport,publicCollectionTruncation}from"../../../internal/collection-snapshot.js";import{tag}from"../../../internal/prefix.js";import{html,nothing}from"lit";import{property,state,query}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{LyraElement}from"../../../internal/lyra-element.js";import{finiteRange}from"../../../internal/numbers.js";import{srOnly}from"../../../internal/a11y.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{styles}from"./knowledge-graph-explorer.styles.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{graphLengthConverter,graphLinkIdentity,normalizeGraphModel}from"../graph/graph-model.js";import{canonicalIdentityList,isNonBlankIdentity}from"../retrieval-identity.js";import"../graph/graph.class.js";import"../graph-legend/graph-legend.class.js";import"../entity-card/entity-card.class.js";import"../neighbor-list/neighbor-list.class.js";import"../path-strip/path-strip.class.js";import"../../overlays/overlay/popover.class.js";import"../../forms/input/input.class.js";import"../../overlays/chip/chip.class.js";import"../../forms/button/button.class.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{LYRA_DEFAULT_graphDataListLimit,LYRA_DEFAULT_graphExplorerFindPath,LYRA_DEFAULT_graphExplorerLabel,LYRA_DEFAULT_graphExplorerPin,LYRA_DEFAULT_graphExplorerPinned,LYRA_DEFAULT_graphExplorerPinnedHeading,LYRA_DEFAULT_graphExplorerSearchLimit,LYRA_DEFAULT_graphExplorerSearchPlaceholder,LYRA_DEFAULT_graphExplorerSearchResultsLabel,LYRA_DEFAULT_graphExplorerUnpin,LYRA_DEFAULT_graphExplorerUnpinned}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_viewerSearchMatchCount,LYRA_DEFAULT_viewerSearchNoMatches}from"../../../internal/default-strings/shared.generated.js";const SEARCH_RESULT_LIMIT=50;function isElementNode(value){if(typeof value!="object"||value===null)return!1;const candidate=value;return candidate.nodeType===1&&typeof candidate.matches=="function"&&typeof candidate.getBoundingClientRect=="function"}class LyraKnowledgeGraphExplorer extends LyraElement{constructor(){super(...arguments),this.nodes=[],this.edges=[],this.nodeTypes=[],this.communities=[],this.entityDetails={},this.pinnedNodeIds=[],this.path=[],this.hiddenTypes=[],this.selectedNodeId=null,this.renderer="svg",this.fitTo="none",this.width=800,this.height=600,this.highlight="selection",this.query="",this.pinLiveText="",this.hoveredNodeId=null,this.activeResult=0,this.activationGeneration=0,this.nodeById=new Map,this.linksByNodeId=new Map,this.degreeByNodeId=new Map,this.communityLabelById=new Map,this.announcements=new AnnouncementSinkController(this,{eager:["polite"]}),this.onVisibilityChange=event=>{event.stopPropagation(),this.hiddenTypes=event.detail.hiddenTypes,this.emit("lr-hidden-types-change",{hiddenTypes:this.hiddenTypes})},this.onVisibilityChangeProposal=event=>{event.stopPropagation()},this.onSearchInput=event=>{event.stopPropagation();const value=event.detail.value;this.query!==value&&(this.query=value,this.emit("lr-search-change",{query:value,matchCount:this.matchingNodes()?.length??0,matchCountExact:!0,activeIndex:-1}))},this.onEntityActivate=event=>{event.stopPropagation(),this.activateEntity(event.detail.entityId)},this.onGraphNodeClick=event=>{const id=event.detail.nodeId;if(!this.canActivateNode(id))return;const generation=this.invalidateActivation();this.setInternalSelectedNodeId(id),this.pendingNodeId=id;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;ownerWindow&&ownerWindow.queueMicrotask(()=>{generation===this.activationGeneration&&this.isConnected&&this.ownerDocument===ownerDocument&&this.pendingNodeId===id&&(this.pendingNodeId=void 0,this.selectedNodeId===id&&this.isVisibleNode(id)&&this.activateEntity(id))})},this.onGraphNativeClick=event=>{const id=this.pendingNodeId;id&&(this.pendingNodeId=void 0,this.openDetailAt(id,this.resolveDirectClickAnchor(event)))},this.onGraphViewportChange=()=>{const el=this.trackedNodeEl,popover=this.popoverEl;if(!el?.isConnected||!popover?.open)return;const rect=el.getBoundingClientRect();popover.showAt({x:rect.left+rect.width/2,y:rect.top,width:rect.width,height:rect.height})},this.onGraphNodeEnter=event=>{this.highlight==="hover"&&(this.hoveredNodeId=event.detail.nodeId)},this.onGraphNodeLeave=event=>{this.highlight==="hover"&&this.hoveredNodeId===event.detail.nodeId&&(this.hoveredNodeId=null)},this.onResultKeyDown=event=>{const buttons=[...this.renderRoot.querySelectorAll('[part="search-result"] button')],index=buttons.indexOf(event.target),next={ArrowDown:index+1,ArrowUp:index-1,Home:0,End:buttons.length-1}[event.key];index<0||next===void 0||(event.preventDefault(),this.activeResult=Math.max(0,Math.min(buttons.length-1,next)),buttons[this.activeResult].focus())},this.onPopoverHide=()=>{this.invalidateActivation(),this.trackedNodeEl=void 0,this.setInternalSelectedNodeId(null)}}static{this.defaultStrings={...super.defaultStrings,fieldRequired:LYRA_DEFAULT_fieldRequired,graphDataListLimit:LYRA_DEFAULT_graphDataListLimit,graphExplorerFindPath:LYRA_DEFAULT_graphExplorerFindPath,graphExplorerLabel:LYRA_DEFAULT_graphExplorerLabel,graphExplorerPin:LYRA_DEFAULT_graphExplorerPin,graphExplorerPinned:LYRA_DEFAULT_graphExplorerPinned,graphExplorerPinnedHeading:LYRA_DEFAULT_graphExplorerPinnedHeading,graphExplorerSearchLimit:LYRA_DEFAULT_graphExplorerSearchLimit,graphExplorerSearchPlaceholder:LYRA_DEFAULT_graphExplorerSearchPlaceholder,graphExplorerSearchResultsLabel:LYRA_DEFAULT_graphExplorerSearchResultsLabel,graphExplorerUnpin:LYRA_DEFAULT_graphExplorerUnpin,graphExplorerUnpinned:LYRA_DEFAULT_graphExplorerUnpinned,viewerSearchMatchCount:LYRA_DEFAULT_viewerSearchMatchCount,viewerSearchNoMatches:LYRA_DEFAULT_viewerSearchNoMatches}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["nodes","edges","nodeTypes","communities","entityDetails","pinnedNodeIds","path","hiddenTypes"])}static{this.styles=[LyraElement.styles,styles,srOnly]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change","lr-pin-change","lr-hidden-types-change"])}get graphModel(){const sources=this.normalizedGraphSources;return(!sources||sources[0]!==this.nodes||sources[1]!==this.edges||sources[2]!==this.nodeTypes||sources[3]!==this.communities)&&(this.normalizedGraphSources=[this.nodes,this.edges,this.nodeTypes,this.communities],this.normalizedGraphModel=normalizeGraphModel(this.nodes,this.edges,this.nodeTypes,this.communities)),this.normalizedGraphModel}get canonicalPinnedNodeIds(){return canonicalIdentityList(this.pinnedNodeIds)}get canonicalHiddenTypes(){return canonicalIdentityList(this.hiddenTypes)}connectedCallback(){super.connectedCallback(),this.hasUpdated&&this.resumePresetActivation()}willUpdate(changed){super.willUpdate(changed),(changed.has("nodes")||changed.has("edges")||changed.has("communities"))&&this.rebuildDerivedCollections(),this.hoveredNodeId&&!this.isVisibleNode(this.hoveredNodeId)&&(this.hoveredNodeId=null),(changed.has("nodes")||changed.has("hiddenTypes"))&&this.selectedNodeId&&!this.isVisibleNode(this.selectedNodeId)&&(this.invalidateActivation(),this.setInternalSelectedNodeId(null),this.popoverEl&&(this.popoverEl.open=!1)),this.hasUpdated&&(this.query??"").trim()&&(changed.has("query")||changed.has("nodes")||changed.has("hiddenTypes")||changed.has("locale")||changed.has("strings"))&&this.announcements.announcePolite(this.searchResultAnnouncement())}updated(changed){if(super.updated(changed),!changed.has("selectedNodeId"))return;const internallyAssigned=this.internalSelectionAssignment!==void 0&&Object.is(this.internalSelectionAssignment.value,this.selectedNodeId);if(this.internalSelectionAssignment=void 0,internallyAssigned)return;const generation=this.invalidateActivation(),id=this.selectedNodeId;if(!isNonBlankIdentity(id)){id!==null&&(this.selectedNodeId=null),this.popoverEl&&(this.popoverEl.open=!1);return}const graph=this.graphEl;graph&&this.isVisibleNode(id)&&this.activatePresetWhenGraphReady(id,graph,generation)}async activatePresetWhenGraphReady(id,graph,generation){for(await graph.updateComplete;generation===this.activationGeneration&&this.isConnected&&graph.isConnected&&this.selectedNodeId===id&&graph.shadowRoot?.querySelector(tag("skeleton"));)if(!await this.waitForActivationFrame(generation))return;generation===this.activationGeneration&&this.isConnected&&this.selectedNodeId===id&&this.isVisibleNode(id)&&await this.activateEntity(id)}waitForActivationFrame(generation){this.cancelActivationFrame();const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;return!ownerWindow||!this.isConnected||generation!==this.activationGeneration?Promise.resolve(!1):new Promise(resolve=>{let settled=!1;const settle=ready=>{settled||(settled=!0,resolve(ready))};let handle;const onPageHide=()=>{this.activationFrameOwner===ownerWindow&&this.activationFrameDocument===ownerDocument&&this.activationFrameResolve===settle&&this.cancelActivationFrame()};try{handle=ownerWindow.requestAnimationFrame(()=>{const current=this.activationFrameId===handle&&this.activationFrameOwner===ownerWindow&&this.activationFrameDocument===ownerDocument&&this.activationFrameResolve===settle&&generation===this.activationGeneration&&this.isConnected&&this.ownerDocument===ownerDocument;current&&this.clearActivationFrameRecord(),settle(current)})}catch{settle(!1);return}this.activationFrameId=handle,this.activationFrameOwner=ownerWindow,this.activationFrameDocument=ownerDocument,this.activationFrameResolve=settle,this.activationFramePageHide=onPageHide,ownerWindow.addEventListener("pagehide",onPageHide,{once:!0})})}clearActivationFrameRecord(){this.activationFramePageHide&&this.activationFrameOwner?.removeEventListener("pagehide",this.activationFramePageHide),this.activationFrameId=void 0,this.activationFrameOwner=void 0,this.activationFrameDocument=void 0,this.activationFrameResolve=void 0,this.activationFramePageHide=void 0}cancelActivationFrame(){const handle=this.activationFrameId,ownerWindow=this.activationFrameOwner,settle=this.activationFrameResolve;this.clearActivationFrameRecord();try{handle!==void 0&&ownerWindow?.cancelAnimationFrame(handle)}finally{settle?.(!1)}}invalidateActivation(){return this.activationGeneration+=1,this.cancelActivationFrame(),this.activationGeneration}resumePresetActivation(){const id=this.selectedNodeId,graph=this.graphEl;if(!id||!graph||!this.isVisibleNode(id))return;const generation=this.invalidateActivation();this.activatePresetWhenGraphReady(id,graph,generation)}setInternalSelectedNodeId(value){Object.is(this.selectedNodeId,value)||(this.internalSelectionAssignment={value},this.selectedNodeId=value,this.emit("lr-selection-change",{selectedNodeId:value,selectedNodeIds:value?[value]:[],selectedEdgeIds:[]}))}disconnectedCallback(){this.invalidateActivation(),this.pendingNodeId=void 0,this.trackedNodeEl=void 0,this.hoveredNodeId=null,super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.invalidateActivation(),this.announcements.adopted(),this.isConnected&&this.resumePresetActivation()}rebuildDerivedCollections(){const model=this.graphModel;this.nodeById=new Map(model.nodes.map(node=>[node.id,node])),this.communityLabelById=new Map(model.communities.map(community=>[community.id,community.label]));const linksByNodeId=new Map,degrees=new Map;for(const link of model.links)for(const id of new Set([link.source,link.target])){const adjacent=linksByNodeId.get(id);adjacent?adjacent.push(link):linksByNodeId.set(id,[link]),degrees.set(id,(degrees.get(id)??0)+1)}this.linksByNodeId=linksByNodeId,this.degreeByNodeId=degrees}isVisibleGraphNode(node){return node.type==null||!this.canonicalHiddenTypes.includes(node.type)}isVisibleNode(id){const node=this.nodeById.get(id);return!!node&&this.isVisibleGraphNode(node)}canActivateNode(id){const node=this.nodeById.get(id);return node?this.isVisibleGraphNode(node):!this.hasUpdated&&this.graphModel.nodes.length===0}nodeLabel(id){const node=this.nodeById.get(id);return node?.label||node?.accessibleLabel||id}degreeOf(id){return this.degreeByNodeId.get(id)??0}entityFor(id){const node=this.nodeById.get(id);if(!node)return;const details=this.entityDetails[id];return{id:node.id,label:node.label||node.accessibleLabel||node.id,type:node.type,communityId:node.communityId,description:details?.description,properties:details?.properties,degree:details?.degree??this.degreeOf(node.id)}}communityLabelFor(communityId){return communityId?this.communityLabelById.get(communityId)??communityId:""}neighborRowsFor(id){const rows=[];for(const link of this.linksByNodeId.get(id)??[])if(link.source===id){const node=this.entityFor(link.target);node&&this.isVisibleNode(link.target)&&rows.push({relation:link.label??"",direction:"out",node})}else if(link.target===id){const node=this.entityFor(link.source);node&&this.isVisibleNode(link.source)&&rows.push({relation:link.label??"",direction:"in",node})}return rows}searchableNamesOf(node){return[node.label,node.accessibleLabel,node.id].filter(name=>typeof name=="string"&&name!=="")}matchingNodes(){const query2=this.query??"",locale=this.effectiveLocale,model=this.graphModel,hidden=this.canonicalHiddenTypes,memo=this.matchesMemo;if(memo?.[0]===query2&&memo[1]===locale&&memo[2]===model&&memo[3]===hidden)return memo[4];const q=query2.trim().toLocaleLowerCase(locale),matches=q?model.nodes.filter(node=>this.isVisibleGraphNode(node)&&this.searchableNamesOf(node).some(name=>name.toLocaleLowerCase(locale).includes(q))):void 0;return this.matchesMemo=[query2,locale,model,hidden,matches],matches}searchResultAnnouncement(matches=this.matchingNodes()){return matches?matches.length===0?this.localize("viewerSearchNoMatches"):this.localize("viewerSearchMatchCount",void 0,{count:getNumberFormat(this.effectiveLocale).format(matches.length),pluralCount:matches.length}):""}neighborIdsOf(id){const ids=new Set;for(const link of this.linksByNodeId.get(id)??[])link.source===id?ids.add(link.target):link.target===id&&ids.add(link.source);return ids}linkKey(link){return graphLinkIdentity(link)}get computedDimmedNodeIds(){if(this.highlight==="none")return[];const matches=this.matchingNodes();if(matches){const matchIds=new Set(matches.map(n=>n.id));return this.graphModel.nodes.filter(n=>!matchIds.has(n.id)).map(n=>n.id)}const focusNodeId=this.selectedNodeId??(this.highlight==="hover"?this.hoveredNodeId:null);if(focusNodeId){const keep=this.neighborIdsOf(focusNodeId);return keep.add(focusNodeId),this.graphModel.nodes.filter(n=>!keep.has(n.id)).map(n=>n.id)}return[]}get computedDimmedLinkIds(){const dimmedNodes=new Set(this.computedDimmedNodeIds);return dimmedNodes.size===0?[]:this.graphModel.links.filter(l=>dimmedNodes.has(l.source)||dimmedNodes.has(l.target)).map(l=>this.linkKey(l))}togglePin(id){if(!isNonBlankIdentity(id))return;const pinnedNodeIds=this.canonicalPinnedNodeIds,wasPinned=pinnedNodeIds.includes(id),next=wasPinned?pinnedNodeIds.filter(existing=>existing!==id):[...pinnedNodeIds,id];this.pinnedNodeIds=next,this.pinLiveText=this.localize(wasPinned?"graphExplorerUnpinned":"graphExplorerPinned",void 0,{label:this.nodeLabel(id)}),this.announcements.announcePolite(this.pinLiveText),this.emit("lr-pin-change",{pinnedNodeIds:next})}requestPath(){const pinnedNodeIds=this.canonicalPinnedNodeIds;if(pinnedNodeIds.length!==2)return;const[sourceNodeId,targetNodeId]=pinnedNodeIds;this.emit("lr-path-request",{sourceNodeId,targetNodeId})}fit(options){this.graphEl?.fit(options)}resetView(){this.graphEl?.fit()}async focusNode(id,options){return this.isVisibleNode(id)?await this.graphEl?.focusNode(id,options)??!1:!1}async activateEntity(id){if(!this.canActivateNode(id))return;const generation=this.invalidateActivation();this.setInternalSelectedNodeId(id),this.trackedNodeEl=void 0;const graph=this.graphEl,focused=graph?await graph.focusNode(id):!1;if(generation!==this.activationGeneration||!this.isConnected||this.selectedNodeId!==id||!this.isVisibleNode(id)||!focused)return;const rect=graph?.getBoundingClientRect();rect&&this.openDetailAt(id,{x:rect.left+rect.width/2,y:rect.top+rect.height/2,width:0,height:0})}openDetailAt(id,rect){const popover=this.popoverEl;popover&&(popover.accessibleLabel=this.entityFor(id)?.label||"",popover.showAt(rect))}resolveDirectClickAnchor(event){if(this.renderer==="canvas")return this.trackedNodeEl=void 0,{x:event.clientX,y:event.clientY,width:0,height:0};const nodeEl=event.composedPath().find(el=>isElementNode(el)&&el.matches('[part="node"]'));if(!nodeEl)return this.trackedNodeEl=void 0,{x:event.clientX,y:event.clientY,width:0,height:0};this.trackedNodeEl=nodeEl;const rect=nodeEl.getBoundingClientRect();return{x:rect.left+rect.width/2,y:rect.top,width:rect.width,height:rect.height}}render(){const groupLabel=retrievalSemanticLabel(this,this.label==null?this.localize("graphExplorerLabel"):this.label),groupRole=retrievalSemanticRole(this,"group"),matches=this.matchingNodes(),detailsLimit=publicCollectionTruncation(this,"entityDetails"),model=this.graphModel,pinnedNodeIds=this.canonicalPinnedNodeIds,hiddenTypes=this.canonicalHiddenTypes,selectedEntity=this.selectedNodeId?this.entityFor(this.selectedNodeId)??null:null,isPinned=this.selectedNodeId!=null&&pinnedNodeIds.includes(this.selectedNodeId),dimmedDeps=[this.highlight,matches,this.selectedNodeId,this.hoveredNodeId,model],detailDeps=[this.selectedNodeId,model,hiddenTypes,this.entityDetails];return html`
1
+ import{__decorate}from"tslib";import{collectionSupport,publicCollectionTruncation}from"../../../internal/collection-snapshot.js";import{tag}from"../../../internal/prefix.js";import{html,nothing}from"lit";import{property,state,query}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{LyraElement}from"../../../internal/lyra-element.js";import{finiteRange}from"../../../internal/numbers.js";import{srOnly}from"../../../internal/a11y.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{styles}from"./knowledge-graph-explorer.styles.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{graphLengthConverter,graphLinkIdentity,normalizeGraphModel}from"../graph/graph-model.js";import{canonicalIdentityList,isNonBlankIdentity}from"../retrieval-identity.js";import"../graph/graph.class.js";import"../graph-legend/graph-legend.class.js";import"../entity-card/entity-card.class.js";import"../neighbor-list/neighbor-list.class.js";import"../path-strip/path-strip.class.js";import"../../overlays/overlay/popover.class.js";import"../../forms/input/input.class.js";import"../../overlays/chip/chip.class.js";import"../../forms/button/button.class.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{LYRA_DEFAULT_graphDataListLimit,LYRA_DEFAULT_graphExplorerFindPath,LYRA_DEFAULT_graphExplorerLabel,LYRA_DEFAULT_graphExplorerPin,LYRA_DEFAULT_graphExplorerPinned,LYRA_DEFAULT_graphExplorerPinnedHeading,LYRA_DEFAULT_graphExplorerSearchLimit,LYRA_DEFAULT_graphExplorerSearchPlaceholder,LYRA_DEFAULT_graphExplorerSearchResultsLabel,LYRA_DEFAULT_graphExplorerUnpin,LYRA_DEFAULT_graphExplorerUnpinned}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_viewerSearchMatchCount,LYRA_DEFAULT_viewerSearchNoMatches}from"../../../internal/default-strings/shared.generated.js";const SEARCH_RESULT_LIMIT=50;function isElementNode(value){if(typeof value!="object"||value===null)return!1;const candidate=value;return candidate.nodeType===1&&typeof candidate.matches=="function"&&typeof candidate.getBoundingClientRect=="function"}class LyraKnowledgeGraphExplorer extends LyraElement{constructor(){super(...arguments),this.nodes=[],this.edges=[],this.nodeTypes=[],this.communities=[],this.entityDetails={},this.pinnedNodeIds=[],this.path=[],this.hiddenTypes=[],this.selectedNodeId=null,this.renderer="svg",this.fitTo="none",this.width=800,this.height=600,this.highlight="selection",this.query="",this.pinLiveText="",this.hoveredNodeId=null,this.activeResult=0,this.activationGeneration=0,this.nodeById=new Map,this.linksByNodeId=new Map,this.degreeByNodeId=new Map,this.communityLabelById=new Map,this.announcements=new AnnouncementSinkController(this,{eager:["polite"]}),this.onVisibilityChange=event=>{event.stopPropagation(),this.hiddenTypes=event.detail.hiddenTypes,this.emit("lr-hidden-types-change",{hiddenTypes:this.hiddenTypes})},this.onVisibilityChangeProposal=event=>{event.stopPropagation()},this.onSearchInput=event=>{event.stopPropagation();const value=event.detail.value;this.query!==value&&(this.query=value,this.emit("lr-search-change",{query:value,matchCount:this.matchingNodes()?.length??0,matchCountExact:!0,activeIndex:-1}))},this.onEntityActivate=event=>{event.stopPropagation(),this.activateEntity(event.detail.entityId)},this.onGraphNodeClick=event=>{const id=event.detail.nodeId;if(!this.canActivateNode(id))return;const generation=this.invalidateActivation();this.setInternalSelectedNodeId(id),this.pendingNodeId=id;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;ownerWindow&&ownerWindow.queueMicrotask(()=>{generation===this.activationGeneration&&this.isConnected&&this.ownerDocument===ownerDocument&&this.pendingNodeId===id&&(this.pendingNodeId=void 0,this.selectedNodeId===id&&this.isVisibleNode(id)&&this.activateEntity(id))})},this.onGraphNativeClick=event=>{const id=this.pendingNodeId;id&&(this.pendingNodeId=void 0,this.openDetailAt(id,this.resolveDirectClickAnchor(event)))},this.onGraphViewportChange=()=>{const el=this.trackedNodeEl,popover=this.popoverEl;if(!el?.isConnected||!popover?.open)return;const rect=el.getBoundingClientRect();popover.showAt({x:rect.left+rect.width/2,y:rect.top,width:rect.width,height:rect.height})},this.onGraphNodeEnter=event=>{this.highlight==="hover"&&(this.hoveredNodeId=event.detail.nodeId)},this.onGraphNodeLeave=event=>{this.highlight==="hover"&&this.hoveredNodeId===event.detail.nodeId&&(this.hoveredNodeId=null)},this.onResultKeyDown=event=>{const buttons=[...this.renderRoot.querySelectorAll('[part="search-result"] button')],index=buttons.indexOf(event.target),next={ArrowDown:index+1,ArrowUp:index-1,Home:0,End:buttons.length-1}[event.key];index<0||next===void 0||(event.preventDefault(),this.activeResult=Math.max(0,Math.min(buttons.length-1,next)),buttons[this.activeResult].focus())},this.onPopoverHide=()=>{this.invalidateActivation(),this.trackedNodeEl=void 0,this.setInternalSelectedNodeId(null)}}static{this.defaultStrings={...super.defaultStrings,fieldRequired:LYRA_DEFAULT_fieldRequired,graphDataListLimit:LYRA_DEFAULT_graphDataListLimit,graphExplorerFindPath:LYRA_DEFAULT_graphExplorerFindPath,graphExplorerLabel:LYRA_DEFAULT_graphExplorerLabel,graphExplorerPin:LYRA_DEFAULT_graphExplorerPin,graphExplorerPinned:LYRA_DEFAULT_graphExplorerPinned,graphExplorerPinnedHeading:LYRA_DEFAULT_graphExplorerPinnedHeading,graphExplorerSearchLimit:LYRA_DEFAULT_graphExplorerSearchLimit,graphExplorerSearchPlaceholder:LYRA_DEFAULT_graphExplorerSearchPlaceholder,graphExplorerSearchResultsLabel:LYRA_DEFAULT_graphExplorerSearchResultsLabel,graphExplorerUnpin:LYRA_DEFAULT_graphExplorerUnpin,graphExplorerUnpinned:LYRA_DEFAULT_graphExplorerUnpinned,viewerSearchMatchCount:LYRA_DEFAULT_viewerSearchMatchCount,viewerSearchNoMatches:LYRA_DEFAULT_viewerSearchNoMatches}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["nodes","edges","nodeTypes","communities","entityDetails","pinnedNodeIds","path","hiddenTypes"])}static{this.styles=[LyraElement.styles,styles,srOnly]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change","lr-pin-change","lr-hidden-types-change"])}get graphModel(){const sources=this.normalizedGraphSources;return(!sources||sources[0]!==this.nodes||sources[1]!==this.edges||sources[2]!==this.nodeTypes||sources[3]!==this.communities)&&(this.normalizedGraphSources=[this.nodes,this.edges,this.nodeTypes,this.communities],this.normalizedGraphModel=normalizeGraphModel(this.nodes,this.edges,this.nodeTypes,this.communities)),this.normalizedGraphModel}get canonicalPinnedNodeIds(){return canonicalIdentityList(this.pinnedNodeIds)}get canonicalHiddenTypes(){return canonicalIdentityList(this.hiddenTypes)}connectedCallback(){super.connectedCallback(),this.hasUpdated&&this.resumePresetActivation()}willUpdate(changed){super.willUpdate(changed),(changed.has("nodes")||changed.has("edges")||changed.has("communities"))&&this.rebuildDerivedCollections(),this.hoveredNodeId&&!this.isVisibleNode(this.hoveredNodeId)&&(this.hoveredNodeId=null),(changed.has("nodes")||changed.has("hiddenTypes"))&&this.selectedNodeId&&!this.isVisibleNode(this.selectedNodeId)&&(this.invalidateActivation(),this.setInternalSelectedNodeId(null),this.popoverEl&&(this.popoverEl.open=!1)),this.hasUpdated&&(this.query??"").trim()&&(changed.has("query")||changed.has("nodes")||changed.has("hiddenTypes")||changed.has("locale")||changed.has("strings"))&&this.announcements.announcePolite(this.searchResultAnnouncement())}updated(changed){if(super.updated(changed),!changed.has("selectedNodeId"))return;const internallyAssigned=this.internalSelectionAssignment!==void 0&&Object.is(this.internalSelectionAssignment.value,this.selectedNodeId);if(this.internalSelectionAssignment=void 0,internallyAssigned)return;const generation=this.invalidateActivation(),id=this.selectedNodeId;if(!isNonBlankIdentity(id)){id!==null&&(this.selectedNodeId=null),this.popoverEl&&(this.popoverEl.open=!1);return}const graph=this.graphEl;graph&&this.isVisibleNode(id)&&this.activatePresetWhenGraphReady(id,graph,generation)}async activatePresetWhenGraphReady(id,graph,generation){for(await graph.updateComplete;generation===this.activationGeneration&&this.isConnected&&graph.isConnected&&this.selectedNodeId===id&&graph.shadowRoot?.querySelector(tag("skeleton"));)if(!await this.waitForActivationFrame(generation))return;generation===this.activationGeneration&&this.isConnected&&this.selectedNodeId===id&&this.isVisibleNode(id)&&await this.activateEntity(id)}waitForActivationFrame(generation){this.cancelActivationFrame();const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;return!ownerWindow||!this.isConnected||generation!==this.activationGeneration?Promise.resolve(!1):new Promise(resolve=>{let settled=!1;const settle=ready=>{settled||(settled=!0,resolve(ready))};let handle;const onPageHide=()=>{this.activationFrameOwner===ownerWindow&&this.activationFrameDocument===ownerDocument&&this.activationFrameResolve===settle&&this.cancelActivationFrame()};try{handle=ownerWindow.requestAnimationFrame(()=>{const current=this.activationFrameId===handle&&this.activationFrameOwner===ownerWindow&&this.activationFrameDocument===ownerDocument&&this.activationFrameResolve===settle&&generation===this.activationGeneration&&this.isConnected&&this.ownerDocument===ownerDocument;current&&this.clearActivationFrameRecord(),settle(current)})}catch{settle(!1);return}this.activationFrameId=handle,this.activationFrameOwner=ownerWindow,this.activationFrameDocument=ownerDocument,this.activationFrameResolve=settle,this.activationFramePageHide=onPageHide,ownerWindow.addEventListener("pagehide",onPageHide,{once:!0})})}clearActivationFrameRecord(){this.activationFramePageHide&&this.activationFrameOwner?.removeEventListener("pagehide",this.activationFramePageHide),this.activationFrameId=void 0,this.activationFrameOwner=void 0,this.activationFrameDocument=void 0,this.activationFrameResolve=void 0,this.activationFramePageHide=void 0}cancelActivationFrame(){const handle=this.activationFrameId,ownerWindow=this.activationFrameOwner,settle=this.activationFrameResolve;this.clearActivationFrameRecord();try{handle!==void 0&&ownerWindow?.cancelAnimationFrame(handle)}finally{settle?.(!1)}}invalidateActivation(){return this.activationGeneration+=1,this.cancelActivationFrame(),this.activationGeneration}resumePresetActivation(){const id=this.selectedNodeId,graph=this.graphEl;if(!id||!graph||!this.isVisibleNode(id))return;const generation=this.invalidateActivation();this.activatePresetWhenGraphReady(id,graph,generation)}setInternalSelectedNodeId(value){Object.is(this.selectedNodeId,value)||(this.internalSelectionAssignment={value},this.selectedNodeId=value,this.emit("lr-selection-change",{selectedNodeId:value,selectedNodeIds:value?[value]:[],selectedEdgeIds:[]}))}disconnectedCallback(){this.invalidateActivation(),this.pendingNodeId=void 0,this.trackedNodeEl=void 0,this.hoveredNodeId=null,super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.invalidateActivation(),this.announcements.adopted(),this.isConnected&&this.resumePresetActivation()}rebuildDerivedCollections(){const model=this.graphModel;this.nodeById=new Map(model.nodes.map(node=>[node.id,node])),this.communityLabelById=new Map(model.communities.map(community=>[community.id,community.label]));const linksByNodeId=new Map,degrees=new Map;for(const link of model.links)for(const id of new Set([link.source,link.target])){const adjacent=linksByNodeId.get(id);adjacent?adjacent.push(link):linksByNodeId.set(id,[link]),degrees.set(id,(degrees.get(id)??0)+1)}this.linksByNodeId=linksByNodeId,this.degreeByNodeId=degrees}isVisibleGraphNode(node){return node.type==null||!this.canonicalHiddenTypes.includes(node.type)}isVisibleNode(id){const node=this.nodeById.get(id);return!!node&&this.isVisibleGraphNode(node)}canActivateNode(id){const node=this.nodeById.get(id);return node?this.isVisibleGraphNode(node):!this.hasUpdated&&this.graphModel.nodes.length===0}nodeLabel(id){const node=this.nodeById.get(id);return node?.label||node?.accessibleLabel||id}degreeOf(id){return this.degreeByNodeId.get(id)??0}entityFor(id){const node=this.nodeById.get(id);if(!node)return;const details=this.entityDetails[id];return{id:node.id,label:node.label||node.accessibleLabel||node.id,type:node.type,communityId:node.communityId,description:details?.description,properties:details?.properties,degree:details?.degree??this.degreeOf(node.id)}}communityLabelFor(communityId){return communityId?this.communityLabelById.get(communityId)??communityId:""}neighborRowsFor(id){const rows=[];for(const link of this.linksByNodeId.get(id)??[])if(link.source===id){const node=this.entityFor(link.target);node&&this.isVisibleNode(link.target)&&rows.push({relation:link.label??"",direction:"out",node})}else if(link.target===id){const node=this.entityFor(link.source);node&&this.isVisibleNode(link.source)&&rows.push({relation:link.label??"",direction:"in",node})}return rows}searchableNamesOf(node){return[node.label,node.accessibleLabel,node.id].filter(name=>typeof name=="string"&&name!=="")}matchingNodes(){const query2=this.query??"",locale=this.effectiveLocale,model=this.graphModel,hidden=this.canonicalHiddenTypes,memo=this.matchesMemo;if(memo?.[0]===query2&&memo[1]===locale&&memo[2]===model&&memo[3]===hidden)return memo[4];const q=query2.trim().toLocaleLowerCase(locale);let matches;if(q){const hiddenTypes=new Set(hidden);matches=model.nodes.filter(node=>(node.type==null||!hiddenTypes.has(node.type))&&this.searchableNamesOf(node).some(name=>name.toLocaleLowerCase(locale).includes(q)))}return this.matchesMemo=[query2,locale,model,hidden,matches],matches}searchResultAnnouncement(matches=this.matchingNodes()){return matches?matches.length===0?this.localize("viewerSearchNoMatches"):this.localize("viewerSearchMatchCount",void 0,{count:getNumberFormat(this.effectiveLocale).format(matches.length),pluralCount:matches.length}):""}neighborIdsOf(id){const ids=new Set;for(const link of this.linksByNodeId.get(id)??[])link.source===id?ids.add(link.target):link.target===id&&ids.add(link.source);return ids}linkKey(link){return graphLinkIdentity(link)}get computedDimmedNodeIds(){if(this.highlight==="none")return[];const matches=this.matchingNodes();if(matches){const matchIds=new Set(matches.map(n=>n.id));return this.graphModel.nodes.filter(n=>!matchIds.has(n.id)).map(n=>n.id)}const focusNodeId=this.selectedNodeId??(this.highlight==="hover"?this.hoveredNodeId:null);if(focusNodeId){const keep=this.neighborIdsOf(focusNodeId);return keep.add(focusNodeId),this.graphModel.nodes.filter(n=>!keep.has(n.id)).map(n=>n.id)}return[]}get computedDimmedLinkIds(){const dimmedNodes=new Set(this.computedDimmedNodeIds);return dimmedNodes.size===0?[]:this.graphModel.links.filter(l=>dimmedNodes.has(l.source)||dimmedNodes.has(l.target)).map(l=>this.linkKey(l))}togglePin(id){if(!isNonBlankIdentity(id))return;const pinnedNodeIds=this.canonicalPinnedNodeIds,wasPinned=pinnedNodeIds.includes(id),next=wasPinned?pinnedNodeIds.filter(existing=>existing!==id):[...pinnedNodeIds,id];this.pinnedNodeIds=next,this.pinLiveText=this.localize(wasPinned?"graphExplorerUnpinned":"graphExplorerPinned",void 0,{label:this.nodeLabel(id)}),this.announcements.announcePolite(this.pinLiveText),this.emit("lr-pin-change",{pinnedNodeIds:next})}requestPath(){const pinnedNodeIds=this.canonicalPinnedNodeIds;if(pinnedNodeIds.length!==2)return;const[sourceNodeId,targetNodeId]=pinnedNodeIds;this.emit("lr-path-request",{sourceNodeId,targetNodeId})}fit(options){this.graphEl?.fit(options)}resetView(){this.graphEl?.fit()}async focusNode(id,options){return this.isVisibleNode(id)?await this.graphEl?.focusNode(id,options)??!1:!1}async activateEntity(id){if(!this.canActivateNode(id))return;const generation=this.invalidateActivation();this.setInternalSelectedNodeId(id),this.trackedNodeEl=void 0;const graph=this.graphEl,focused=graph?await graph.focusNode(id):!1;if(generation!==this.activationGeneration||!this.isConnected||this.selectedNodeId!==id||!this.isVisibleNode(id)||!focused)return;const rect=graph?.getBoundingClientRect();rect&&this.openDetailAt(id,{x:rect.left+rect.width/2,y:rect.top+rect.height/2,width:0,height:0})}openDetailAt(id,rect){const popover=this.popoverEl;popover&&(popover.accessibleLabel=this.entityFor(id)?.label||"",popover.showAt(rect))}resolveDirectClickAnchor(event){if(this.renderer==="canvas")return this.trackedNodeEl=void 0,{x:event.clientX,y:event.clientY,width:0,height:0};const nodeEl=event.composedPath().find(el=>isElementNode(el)&&el.matches('[part="node"]'));if(!nodeEl)return this.trackedNodeEl=void 0,{x:event.clientX,y:event.clientY,width:0,height:0};this.trackedNodeEl=nodeEl;const rect=nodeEl.getBoundingClientRect();return{x:rect.left+rect.width/2,y:rect.top,width:rect.width,height:rect.height}}render(){const groupLabel=retrievalSemanticLabel(this,this.label==null?this.localize("graphExplorerLabel"):this.label),groupRole=retrievalSemanticRole(this,"group"),matches=this.matchingNodes(),detailsLimit=publicCollectionTruncation(this,"entityDetails"),model=this.graphModel,pinnedNodeIds=this.canonicalPinnedNodeIds,hiddenTypes=this.canonicalHiddenTypes,selectedEntity=this.selectedNodeId?this.entityFor(this.selectedNodeId)??null:null,isPinned=this.selectedNodeId!=null&&pinnedNodeIds.includes(this.selectedNodeId),dimmedDeps=[this.highlight,matches,this.selectedNodeId,this.hoveredNodeId,model],detailDeps=[this.selectedNodeId,model,hiddenTypes,this.entityDetails];return html`
2
2
  <div
3
3
  part="base"
4
4
  role=${groupRole??nothing}
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{LyraElement}from"../../../internal/lyra-element.js";import{firstByRetrievalIdentity}from"../retrieval-identity.js";import{expandIcon}from"../../../internal/icons.js";import{finiteCount}from"../../../internal/numbers.js";import{getCollator,getListFormat,getNumberFormat}from"../../../internal/intl-cache.js";import"../../overlays/empty/empty.class.js";import{styles}from"./neighbor-list.styles.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{LYRA_DEFAULT_neighborExpand,LYRA_DEFAULT_neighborGroupHeader,LYRA_DEFAULT_neighborListEmpty,LYRA_DEFAULT_neighborListLabel,LYRA_DEFAULT_neighborRowLabel}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_neighborDirectionBoth,LYRA_DEFAULT_neighborDirectionIn,LYRA_DEFAULT_neighborDirectionOut}from"../../../internal/default-strings/shared.generated.js";let virtualListRegistration;class LyraNeighborList extends LyraElement{constructor(){super(...arguments),this.rows=[],this.types=[],this.groupByRelation=!1,this.expandable=!1,this.virtualizeAt=100,this.sortedRowsCache=[],this.hasComputedRows=!1,this.processedSignature="",this.renderRow=item=>this.renderNeighborRow(item),this.virtualListKeyFunction=item=>item.node.id}static{this.defaultStrings={...super.defaultStrings,neighborDirectionBoth:LYRA_DEFAULT_neighborDirectionBoth,neighborDirectionIn:LYRA_DEFAULT_neighborDirectionIn,neighborDirectionOut:LYRA_DEFAULT_neighborDirectionOut,neighborExpand:LYRA_DEFAULT_neighborExpand,neighborGroupHeader:LYRA_DEFAULT_neighborGroupHeader,neighborListEmpty:LYRA_DEFAULT_neighborListEmpty,neighborListLabel:LYRA_DEFAULT_neighborListLabel,neighborRowLabel:LYRA_DEFAULT_neighborRowLabel}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["rows","types"])}static{this.styles=[LyraElement.styles,styles]}get effectiveVirtualizeAt(){return finiteCount(this.virtualizeAt,100)}willUpdate(changed){super.willUpdate(changed);const signature=`${this.effectiveLocale} ${this.groupByRelation}`;(!this.hasComputedRows||changed.has("rows")||changed.has("groupByRelation")||signature!==this.processedSignature)&&(this.hasComputedRows=!0,this.processedSignature=signature,this.sortedRowsCache=this.computeSortedRows(),this.groupsCache=this.computeGroups(this.sortedRowsCache)),this.sortedRowsCache.length>this.effectiveVirtualizeAt&&(virtualListRegistration??=import("../../layout/virtual-list/virtual-list.js").catch(()=>virtualListRegistration=void 0))}sortedRows(){return this.sortedRowsCache}computeSortedRows(){const rows=firstByRetrievalIdentity(this.rows,row=>row?.node?.id);return this.groupByRelation?rows.sort((a,b)=>getCollator(this.effectiveLocale).compare(a.relation,b.relation)):rows}groups(sorted){return sorted===this.sortedRowsCache?this.groupsCache:this.computeGroups(sorted)}computeGroups(sorted){if(!this.groupByRelation)return;const groups=[],counts=new Map;for(const row of sorted)counts.set(row.relation,(counts.get(row.relation)??0)+1);const numberFormat=getNumberFormat(this.effectiveLocale);let lastRelation;return sorted.forEach((row,i)=>{if(row.relation!==lastRelation){const count=numberFormat.format(counts.get(row.relation)??0);groups.push({key:row.relation,label:this.localize("neighborGroupHeader",void 0,{relation:row.relation,count}),startIndex:i}),lastRelation=row.relation}}),groups}directionGlyph(direction){return direction==="both"?"↔":direction==="out"?"→":"←"}directionText(direction){return this.localize(direction==="in"?"neighborDirectionIn":direction==="out"?"neighborDirectionOut":"neighborDirectionBoth")}renderNeighborRow(row){const nodeLabel=row.node.label||row.node.id,directionText=this.directionText(row.direction),accessibleName=this.localize("neighborRowLabel",void 0,{label:nodeLabel,relation:row.relation,direction:directionText}),nodeType=typeof row.node.type=="string"&&row.node.type.trim()!==""?row.node.type:void 0;this.typeLabels?.[0]!==this.types&&(this.typeLabels=[this.types,new Map(firstByRetrievalIdentity(this.types,type=>type?.id).map(type=>[type.id,type.label]))]);const meta=[nodeType&&(this.typeLabels[1].get(nodeType)??nodeType),row.node.degree!=null?getNumberFormat(this.effectiveLocale).format(finiteCount(row.node.degree)):void 0].filter(v=>typeof v=="string"&&v!==""),metaText=getListFormat(this.effectiveLocale,{style:"short",type:"unit"}).format(meta);return html`
1
+ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{LyraElement}from"../../../internal/lyra-element.js";import{firstByRetrievalIdentity}from"../retrieval-identity.js";import{expandIcon}from"../../../internal/icons.js";import{finiteCount}from"../../../internal/numbers.js";import{getCollator,getListFormat,getNumberFormat}from"../../../internal/intl-cache.js";import"../../overlays/empty/empty.class.js";import{styles}from"./neighbor-list.styles.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{LYRA_DEFAULT_neighborExpand,LYRA_DEFAULT_neighborGroupHeader,LYRA_DEFAULT_neighborListEmpty,LYRA_DEFAULT_neighborListLabel,LYRA_DEFAULT_neighborRowLabel}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_neighborDirectionBoth,LYRA_DEFAULT_neighborDirectionIn,LYRA_DEFAULT_neighborDirectionOut}from"../../../internal/default-strings/shared.generated.js";let virtualListRegistration;class LyraNeighborList extends LyraElement{constructor(){super(...arguments),this.rows=[],this.types=[],this.groupByRelation=!1,this.expandable=!1,this.virtualizeAt=100,this.sortedRowsCache=[],this.hasComputedRows=!1,this.processedSignature="",this.renderRow=item=>this.renderNeighborRow(item),this.virtualListKeyFunction=item=>item.node.id}static{this.defaultStrings={...super.defaultStrings,neighborDirectionBoth:LYRA_DEFAULT_neighborDirectionBoth,neighborDirectionIn:LYRA_DEFAULT_neighborDirectionIn,neighborDirectionOut:LYRA_DEFAULT_neighborDirectionOut,neighborExpand:LYRA_DEFAULT_neighborExpand,neighborGroupHeader:LYRA_DEFAULT_neighborGroupHeader,neighborListEmpty:LYRA_DEFAULT_neighborListEmpty,neighborListLabel:LYRA_DEFAULT_neighborListLabel,neighborRowLabel:LYRA_DEFAULT_neighborRowLabel}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["rows","types"])}static{this.styles=[LyraElement.styles,styles]}get effectiveVirtualizeAt(){return finiteCount(this.virtualizeAt,100)}willUpdate(changed){super.willUpdate(changed);const signature=`${this.effectiveLocale} ${this.groupByRelation}`;(!this.hasComputedRows||changed.has("rows")||changed.has("groupByRelation")||signature!==this.processedSignature)&&(this.hasComputedRows=!0,this.processedSignature=signature,this.sortedRowsCache=this.computeSortedRows(),this.groupsCache=this.computeGroups(this.sortedRowsCache)),this.sortedRowsCache.length>this.effectiveVirtualizeAt&&(virtualListRegistration??=import("../../layout/virtual-list/virtual-list.js").catch(()=>virtualListRegistration=void 0))}sortedRows(){return this.sortedRowsCache}computeSortedRows(){const rows=firstByRetrievalIdentity(this.rows,row=>row?.node?.id);if(!this.groupByRelation)return rows;const compare=getCollator(this.effectiveLocale).compare;return rows.sort((a,b)=>compare(a.relation,b.relation))}groups(sorted){return sorted===this.sortedRowsCache?this.groupsCache:this.computeGroups(sorted)}computeGroups(sorted){if(!this.groupByRelation)return;const groups=[],counts=new Map;for(const row of sorted)counts.set(row.relation,(counts.get(row.relation)??0)+1);const numberFormat=getNumberFormat(this.effectiveLocale);let lastRelation;return sorted.forEach((row,i)=>{if(row.relation!==lastRelation){const count=numberFormat.format(counts.get(row.relation)??0);groups.push({key:row.relation,label:this.localize("neighborGroupHeader",void 0,{relation:row.relation,count}),startIndex:i}),lastRelation=row.relation}}),groups}directionGlyph(direction){return direction==="both"?"↔":direction==="out"?"→":"←"}directionText(direction){return this.localize(direction==="in"?"neighborDirectionIn":direction==="out"?"neighborDirectionOut":"neighborDirectionBoth")}renderNeighborRow(row){const nodeLabel=row.node.label||row.node.id,directionText=this.directionText(row.direction),accessibleName=this.localize("neighborRowLabel",void 0,{label:nodeLabel,relation:row.relation,direction:directionText}),nodeType=typeof row.node.type=="string"&&row.node.type.trim()!==""?row.node.type:void 0;this.typeLabels?.[0]!==this.types&&(this.typeLabels=[this.types,new Map(firstByRetrievalIdentity(this.types,type=>type?.id).map(type=>[type.id,type.label]))]);const meta=[nodeType&&(this.typeLabels[1].get(nodeType)??nodeType),row.node.degree!=null?getNumberFormat(this.effectiveLocale).format(finiteCount(row.node.degree)):void 0].filter(v=>typeof v=="string"&&v!==""),metaText=getListFormat(this.effectiveLocale,{style:"short",type:"unit"}).format(meta);return html`
2
2
  <button
3
3
  part="node-label"
4
4
  type="button"
@@ -186,4 +186,4 @@ announce:boolean;
186
186
  * says exactly what this region is. An explicit empty string clears the fallback. A non-empty
187
187
  * host `aria-label` makes the host the sole overall owner; an explicitly empty host label stays
188
188
  * empty on the region. */
189
- label?:string;private expandedChunkIds;private pendingFocusTarget;private previousProcessedChunkIds;private focusRestoreGeneration;private isMounting;private initialStateAnnounced;private connectionGeneration;private errorAnnouncementSink?;private emptyAnnouncementSink?;private readonly retrievalChunkKey;private wasEmptyPresented;private processedChunksCache?;private processedGroupingLocaleSignature;connectedCallback():void;disconnectedCallback():void;private deepActiveElement;private chunkAnchor;private renderedChunkIds;protected willUpdate(changed:PropertyValues<this>):void;protected updated(changed:PropertyValues<this>):void;private announcePresentedState;private restoreControlledFocus;private get effectiveVirtualizeAt();private canonicalChunks;private normalizedSelectedChunkIds;private get processedChunks();private computeProcessedChunks;private orderedGroupKeys;private bucketed;private stopOwnedEvent;private reportSelection;private toggleSelect;private stopRowToggle;private onChunkToggle;private readonly rowChunks;private rowChunksFor;private renderMetadata;private renderRow;private renderLoadMoreFooter;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-retrieval-results':LyraRetrievalResults;}}
189
+ label?:string;private expandedChunkIds;private pendingFocusTarget;private previousProcessedChunkIds;private focusRestoreGeneration;private isMounting;private initialStateAnnounced;private connectionGeneration;private errorAnnouncementSink?;private emptyAnnouncementSink?;private readonly retrievalChunkKey;private wasEmptyPresented;private processedChunksCache?;private processedGroupingLocaleSignature;connectedCallback():void;disconnectedCallback():void;private deepActiveElement;private chunkAnchor;private renderedChunkIds;protected willUpdate(changed:PropertyValues<this>):void;protected updated(changed:PropertyValues<this>):void;private announcePresentedState;private restoreControlledFocus;private get effectiveVirtualizeAt();private canonicalChunks;private normalizedSelectedChunkIds;private get processedChunks();private computeProcessedChunks;private orderedGroupKeys;private bucketed;private stopOwnedEvent;private reportSelection;private toggleSelect;private stopRowToggle;private onChunkToggle;private readonly rowChunks;private rowChunksFor;private renderMetadata;private selectedMembership?;private isChunkSelected;private renderRow;private renderLoadMoreFooter;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-retrieval-results':LyraRetrievalResults;}}
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport,writeNormalizedOwnedCollection}from"../../../internal/collection-snapshot.js";import{tag}from"../../../internal/prefix.js";import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{LyraElement}from"../../../internal/lyra-element.js";import{firstByRetrievalIdentity,canonicalIdentityList,isValidRetrievalChunk}from"../retrieval-identity.js";import{finiteCount,finiteRange}from"../../../internal/numbers.js";import{styles}from"./retrieval-results.styles.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{renderRetrievalMetadata}from"../retrieval-metadata.js";import{deepActiveElementIn}from"../../../internal/active-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{announceAfterFirstPaint}from"../retrieval-announcements.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{LYRA_DEFAULT_chunkInspectorEmpty,LYRA_DEFAULT_chunkInspectorLabel,LYRA_DEFAULT_retrievalResultsSelectRowOrdinal,LYRA_DEFAULT_untitledSource,LYRA_DEFAULT_valueTruncated}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_loadMore,LYRA_DEFAULT_valueInvalid}from"../../../internal/default-strings/shared.generated.js";function toLyraChunk(chunk){return{id:chunk.id,text:chunk.text,score:chunk.score,sourceId:chunk.source.id,title:chunk.source.name,anchor:chunk.locator,page:chunk.locator?.kind==="page"?chunk.locator.page:void 0}}function safeScore(score){return finiteRange(score,0,0,1)}class LyraRetrievalResults extends LyraElement{constructor(){super(...arguments),this.chunks=[],this.selectedChunkIds=[],this.withoutSelection=!1,this.withoutDedupe=!1,this.sort="score",this.grouping="none",this.presentation="expanded",this.thresholds={high:.75,medium:.5},this.virtualizeAt=50,this.activeChunkId="",this.loading=!1,this.hasMore=!1,this.errorText="",this.announce=!1,this.expandedChunkIds=[],this.previousProcessedChunkIds=[],this.focusRestoreGeneration=0,this.isMounting=!0,this.initialStateAnnounced=!1,this.connectionGeneration=0,this.retrievalChunkKey=item=>item.id,this.wasEmptyPresented=!1,this.processedGroupingLocaleSignature="",this.stopOwnedEvent=event=>{event.stopPropagation()},this.stopRowToggle=event=>{event.stopPropagation()},this.onChunkToggle=event=>{event.stopPropagation();const{chunkId,expanded}=event.detail,rest=this.expandedChunkIds.filter(id=>id!==chunkId);this.expandedChunkIds=expanded?[...rest,chunkId]:rest},this.rowChunks=new WeakMap,this.renderRow=(item,index,total)=>{const chunk=item,selected=this.selectedChunkIds.includes(chunk.id),rowLabel=chunk.source.name||this.localize("untitledSource");return html`
1
+ import{__decorate}from"tslib";import{collectionSupport,writeNormalizedOwnedCollection}from"../../../internal/collection-snapshot.js";import{tag}from"../../../internal/prefix.js";import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{LyraElement}from"../../../internal/lyra-element.js";import{firstByRetrievalIdentity,canonicalIdentityList,isValidRetrievalChunk}from"../retrieval-identity.js";import{finiteCount,finiteRange}from"../../../internal/numbers.js";import{styles}from"./retrieval-results.styles.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{renderRetrievalMetadata}from"../retrieval-metadata.js";import{deepActiveElementIn}from"../../../internal/active-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{announceAfterFirstPaint}from"../retrieval-announcements.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{LYRA_DEFAULT_chunkInspectorEmpty,LYRA_DEFAULT_chunkInspectorLabel,LYRA_DEFAULT_retrievalResultsSelectRowOrdinal,LYRA_DEFAULT_untitledSource,LYRA_DEFAULT_valueTruncated}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_loadMore,LYRA_DEFAULT_valueInvalid}from"../../../internal/default-strings/shared.generated.js";function toLyraChunk(chunk){return{id:chunk.id,text:chunk.text,score:chunk.score,sourceId:chunk.source.id,title:chunk.source.name,anchor:chunk.locator,page:chunk.locator?.kind==="page"?chunk.locator.page:void 0}}function safeScore(score){return finiteRange(score,0,0,1)}class LyraRetrievalResults extends LyraElement{constructor(){super(...arguments),this.chunks=[],this.selectedChunkIds=[],this.withoutSelection=!1,this.withoutDedupe=!1,this.sort="score",this.grouping="none",this.presentation="expanded",this.thresholds={high:.75,medium:.5},this.virtualizeAt=50,this.activeChunkId="",this.loading=!1,this.hasMore=!1,this.errorText="",this.announce=!1,this.expandedChunkIds=[],this.previousProcessedChunkIds=[],this.focusRestoreGeneration=0,this.isMounting=!0,this.initialStateAnnounced=!1,this.connectionGeneration=0,this.retrievalChunkKey=item=>item.id,this.wasEmptyPresented=!1,this.processedGroupingLocaleSignature="",this.stopOwnedEvent=event=>{event.stopPropagation()},this.stopRowToggle=event=>{event.stopPropagation()},this.onChunkToggle=event=>{event.stopPropagation();const{chunkId,expanded}=event.detail,rest=this.expandedChunkIds.filter(id=>id!==chunkId);this.expandedChunkIds=expanded?[...rest,chunkId]:rest},this.rowChunks=new WeakMap,this.renderRow=(item,index,total)=>{const chunk=item,selected=this.isChunkSelected(chunk.id),rowLabel=chunk.source.name||this.localize("untitledSource");return html`
2
2
  ${this.withoutSelection?nothing:html`<lr-checkbox
3
3
  part="select"
4
4
  data-chunk-id=${chunk.id}
@@ -31,7 +31,7 @@ import{__decorate}from"tslib";import{collectionSupport,writeNormalizedOwnedColle
31
31
  ></lr-chunk-inspector>
32
32
  ${this.presentation==="expanded"?this.renderMetadata(chunk.metadata):nothing}
33
33
  </div>
34
- `}}static{this.defaultStrings={...super.defaultStrings,chunkInspectorEmpty:LYRA_DEFAULT_chunkInspectorEmpty,chunkInspectorLabel:LYRA_DEFAULT_chunkInspectorLabel,loadMore:LYRA_DEFAULT_loadMore,retrievalResultsSelectRowOrdinal:LYRA_DEFAULT_retrievalResultsSelectRowOrdinal,untitledSource:LYRA_DEFAULT_untitledSource,valueInvalid:LYRA_DEFAULT_valueInvalid,valueTruncated:LYRA_DEFAULT_valueTruncated}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["chunks","selectedChunkIds","groupOrder"])}static{this.styles=[LyraElement.styles,styles]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change","lr-select","lr-chunk-open"])}connectedCallback(){super.connectedCallback(),this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this}),this.emptyAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this});const generation=++this.connectionGeneration;announceAfterFirstPaint(this,()=>generation===this.connectionGeneration,()=>{!this.announce||this.initialStateAnnounced||(this.initialStateAnnounced=!0,this.announcePresentedState())})}disconnectedCallback(){this.isMounting=!0,this.connectionGeneration+=1,this.errorAnnouncementSink?.release(),this.errorAnnouncementSink=void 0,this.emptyAnnouncementSink?.release(),this.emptyAnnouncementSink=void 0,this.wasEmptyPresented=!1,super.disconnectedCallback()}deepActiveElement(){return deepActiveElementIn(this.isConnected?this.shadowRoot:null)}chunkAnchor(start){let current=start;for(;current&&current!==this;){if(current.hasAttribute("data-chunk-id"))return current;if(current.parentElement){current=current.parentElement;continue}const root=current.getRootNode();current=root.nodeType===11&&"host"in root?root.host:null}return null}renderedChunkIds(){const roots=[this.renderRoot],virtualList=this.renderRoot.querySelector(tag("virtual-list"));return virtualList?.shadowRoot&&roots.push(virtualList.shadowRoot),roots.flatMap(root=>[...root.querySelectorAll(`${tag("chunk-inspector")}[data-chunk-id]`)].map(element=>element.getAttribute("data-chunk-id")).filter(id=>id!==null))}willUpdate(changed){super.willUpdate(changed);const groupingLocaleSignature=this.grouping==="source"?`${this.effectiveLocale}\0${this.localize("untitledSource")}`:"";if((this.processedChunksCache===void 0||changed.has("chunks")||changed.has("withoutDedupe")||changed.has("sort")||changed.has("grouping")||changed.has("groupBy")||changed.has("groupLabel")||changed.has("groupOrder")||groupingLocaleSignature!==this.processedGroupingLocaleSignature)&&(this.processedGroupingLocaleSignature=groupingLocaleSignature,this.processedChunksCache=this.computeProcessedChunks()),changed.has("chunks")){const present=new Set(this.processedChunks.chunks.map(chunk=>chunk.id)),kept=this.expandedChunkIds.filter(id=>present.has(id));kept.length!==this.expandedChunkIds.length&&(this.expandedChunkIds=kept)}if(changed.has("chunks")||changed.has("selectedChunkIds")){const normalized=this.normalizedSelectedChunkIds();if(normalized.length!==this.selectedChunkIds.length||normalized.some((id,index)=>id!==this.selectedChunkIds[index])){const shouldAnnounce=this.hasUpdated&&changed.has("chunks");writeNormalizedOwnedCollection(this,"selectedChunkIds",()=>{this.selectedChunkIds=normalized}),shouldAnnounce&&this.reportSelection(normalized)}}if(!changed.has("chunks")&&!changed.has("withoutDedupe")&&!changed.has("sort")&&!changed.has("grouping")&&!changed.has("groupBy")&&!changed.has("groupLabel")&&!changed.has("groupOrder")&&!changed.has("presentation")&&!changed.has("withoutSelection")&&!changed.has("virtualizeAt")&&!changed.has("loading")&&!changed.has("errorText"))return;const focusedId=this.chunkAnchor(this.deepActiveElement())?.getAttribute("data-chunk-id");if(!focusedId)return;const previousIds=this.previousProcessedChunkIds.length?this.previousProcessedChunkIds:this.renderedChunkIds(),focusedIndex=Math.max(0,previousIds.indexOf(focusedId)),nextChunks=this.errorText?[]:this.processedChunks.chunks;if(nextChunks.length===0){this.pendingFocusTarget="base";return}const survivingIndex=nextChunks.findIndex(chunk=>chunk.id===focusedId),nextIndex=survivingIndex>=0?survivingIndex:Math.min(focusedIndex,nextChunks.length-1);this.pendingFocusTarget=nextChunks[nextIndex].id}updated(changed){super.updated(changed);const wasMounting=this.isMounting;this.isMounting=!1,!wasMounting&&changed.has("errorText")&&this.errorText!==""&&this.isConnected&&(this.initialStateAnnounced=!0,this.errorAnnouncementSink?.announce(this.errorText));const emptyPresented=!this.loading&&this.errorText===""&&this.processedChunks.chunks.length===0;!wasMounting&&!this.wasEmptyPresented&&emptyPresented&&this.isConnected&&(this.initialStateAnnounced=!0,this.emptyAnnouncementSink?.announce(this.localize("chunkInspectorEmpty"))),this.wasEmptyPresented=emptyPresented,this.previousProcessedChunkIds=this.errorText?[]:this.processedChunks.chunks.map(chunk=>chunk.id);const generation=++this.focusRestoreGeneration,target=this.pendingFocusTarget;target!==void 0&&(this.pendingFocusTarget=void 0,this.restoreControlledFocus(target,generation))}announcePresentedState(){if(this.errorText!==""){this.errorAnnouncementSink?.announce(this.errorText);return}!this.loading&&this.processedChunks.chunks.length===0&&this.emptyAnnouncementSink?.announce(this.localize("chunkInspectorEmpty"))}async restoreControlledFocus(target,generation){if(await this.updateComplete,generation!==this.focusRestoreGeneration||!this.isConnected)return;if(target==="base"){this.renderRoot.querySelector('[part="base"]')?.focus();return}const virtualList=this.renderRoot.querySelector(tag("virtual-list"));if(await virtualList?.updateComplete,generation!==this.focusRestoreGeneration||!this.isConnected)return;const roots=[this.renderRoot];virtualList?.shadowRoot&&roots.push(virtualList.shadowRoot);const candidates=roots.flatMap(root=>[...root.querySelectorAll("[data-chunk-id]")]),checkbox=candidates.find(element=>element.localName===tag("checkbox")&&element.getAttribute("data-chunk-id")===target);if(checkbox){checkbox.focus();return}const inspector=candidates.find(element=>element.localName===tag("chunk-inspector")&&element.getAttribute("data-chunk-id")===target);await inspector?.updateComplete,!(generation!==this.focusRestoreGeneration||!this.isConnected)&&inspector?.shadowRoot?.querySelector('[part="open-button"]')?.focus()}get effectiveVirtualizeAt(){return finiteCount(this.virtualizeAt,50)}canonicalChunks(){return firstByRetrievalIdentity(Array.isArray(this.chunks)?this.chunks.filter(isValidRetrievalChunk):[],chunk=>chunk.id)}normalizedSelectedChunkIds(){const validIds=new Set(this.canonicalChunks().map(chunk=>chunk.id));return canonicalIdentityList(this.selectedChunkIds).filter(id=>validIds.has(id))}get processedChunks(){return this.processedChunksCache??=this.computeProcessedChunks()}computeProcessedChunks(){const canonical=this.canonicalChunks(),sorted=this.sort==="score"?canonical.sort((a,b)=>safeScore(b.score)-safeScore(a.score)):canonical;if(this.grouping==="source")return this.bucketed(sorted,chunk=>chunk.source.id,(_id,groupChunks)=>groupChunks[0].source.name||this.localize("untitledSource"));if(this.grouping==="custom"&&this.groupBy){const groupBy=this.groupBy;return this.bucketed(sorted,groupBy,(id,groupChunks)=>this.groupLabel?.(id,groupChunks)??id)}return{chunks:sorted,groups:[]}}orderedGroupKeys(grouped){const firstSeen=[...grouped.keys()];if(this.grouping!=="custom"||!this.groupOrder)return firstSeen;if(typeof this.groupOrder=="function")return firstSeen.sort(this.groupOrder);const ordered=[...new Set(this.groupOrder)].filter(id=>grouped.has(id)),listed=new Set(ordered);return[...ordered,...firstSeen.filter(id=>!listed.has(id))]}bucketed(sorted,keyOf,labelOf){const grouped=new Map;for(const chunk of sorted){const key=keyOf(chunk),existing=grouped.get(key);existing?existing.push(chunk):grouped.set(key,[chunk])}const rows=[],groups=[];for(const key of this.orderedGroupKeys(grouped)){const groupChunks=grouped.get(key);!groupChunks||groupChunks.length===0||(groups.push({key,label:labelOf(key,groupChunks),startIndex:rows.length}),rows.push(...groupChunks))}return{chunks:rows,groups}}reportSelection(chunkIds){const selected=new Set(chunkIds),chunks=this.canonicalChunks().filter(chunk=>selected.has(chunk.id));this.emit("lr-selection-change",{selectedChunkIds:chunkIds,chunks}),this.emit("lr-select",{chunkIds,chunks})}toggleSelect(chunk){const next=new Set(this.normalizedSelectedChunkIds());next.has(chunk.id)?next.delete(chunk.id):next.add(chunk.id),this.selectedChunkIds=[...next],this.reportSelection(this.selectedChunkIds)}rowChunksFor(chunk){let row=this.rowChunks.get(chunk);return row||this.rowChunks.set(chunk,row=[toLyraChunk(chunk)]),row}renderMetadata(metadata){return renderRetrievalMetadata(metadata,this.effectiveLocale,this.localize("valueInvalid"),this.localize("valueTruncated"))}renderLoadMoreFooter(){return this.hasMore?html`
34
+ `}}static{this.defaultStrings={...super.defaultStrings,chunkInspectorEmpty:LYRA_DEFAULT_chunkInspectorEmpty,chunkInspectorLabel:LYRA_DEFAULT_chunkInspectorLabel,loadMore:LYRA_DEFAULT_loadMore,retrievalResultsSelectRowOrdinal:LYRA_DEFAULT_retrievalResultsSelectRowOrdinal,untitledSource:LYRA_DEFAULT_untitledSource,valueInvalid:LYRA_DEFAULT_valueInvalid,valueTruncated:LYRA_DEFAULT_valueTruncated}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["chunks","selectedChunkIds","groupOrder"])}static{this.styles=[LyraElement.styles,styles]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change","lr-select","lr-chunk-open"])}connectedCallback(){super.connectedCallback(),this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this}),this.emptyAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this});const generation=++this.connectionGeneration;announceAfterFirstPaint(this,()=>generation===this.connectionGeneration,()=>{!this.announce||this.initialStateAnnounced||(this.initialStateAnnounced=!0,this.announcePresentedState())})}disconnectedCallback(){this.isMounting=!0,this.connectionGeneration+=1,this.errorAnnouncementSink?.release(),this.errorAnnouncementSink=void 0,this.emptyAnnouncementSink?.release(),this.emptyAnnouncementSink=void 0,this.wasEmptyPresented=!1,super.disconnectedCallback()}deepActiveElement(){return deepActiveElementIn(this.isConnected?this.shadowRoot:null)}chunkAnchor(start){let current=start;for(;current&&current!==this;){if(current.hasAttribute("data-chunk-id"))return current;if(current.parentElement){current=current.parentElement;continue}const root=current.getRootNode();current=root.nodeType===11&&"host"in root?root.host:null}return null}renderedChunkIds(){const roots=[this.renderRoot],virtualList=this.renderRoot.querySelector(tag("virtual-list"));return virtualList?.shadowRoot&&roots.push(virtualList.shadowRoot),roots.flatMap(root=>[...root.querySelectorAll(`${tag("chunk-inspector")}[data-chunk-id]`)].map(element=>element.getAttribute("data-chunk-id")).filter(id=>id!==null))}willUpdate(changed){super.willUpdate(changed);const groupingLocaleSignature=this.grouping==="source"?`${this.effectiveLocale}\0${this.localize("untitledSource")}`:"";if((this.processedChunksCache===void 0||changed.has("chunks")||changed.has("withoutDedupe")||changed.has("sort")||changed.has("grouping")||changed.has("groupBy")||changed.has("groupLabel")||changed.has("groupOrder")||groupingLocaleSignature!==this.processedGroupingLocaleSignature)&&(this.processedGroupingLocaleSignature=groupingLocaleSignature,this.processedChunksCache=this.computeProcessedChunks()),changed.has("chunks")){const present=new Set(this.processedChunks.chunks.map(chunk=>chunk.id)),kept=this.expandedChunkIds.filter(id=>present.has(id));kept.length!==this.expandedChunkIds.length&&(this.expandedChunkIds=kept)}if(changed.has("chunks")||changed.has("selectedChunkIds")){const normalized=this.normalizedSelectedChunkIds();if(normalized.length!==this.selectedChunkIds.length||normalized.some((id,index)=>id!==this.selectedChunkIds[index])){const shouldAnnounce=this.hasUpdated&&changed.has("chunks");writeNormalizedOwnedCollection(this,"selectedChunkIds",()=>{this.selectedChunkIds=normalized}),shouldAnnounce&&this.reportSelection(normalized)}}if(!changed.has("chunks")&&!changed.has("withoutDedupe")&&!changed.has("sort")&&!changed.has("grouping")&&!changed.has("groupBy")&&!changed.has("groupLabel")&&!changed.has("groupOrder")&&!changed.has("presentation")&&!changed.has("withoutSelection")&&!changed.has("virtualizeAt")&&!changed.has("loading")&&!changed.has("errorText"))return;const focusedId=this.chunkAnchor(this.deepActiveElement())?.getAttribute("data-chunk-id");if(!focusedId)return;const previousIds=this.previousProcessedChunkIds.length?this.previousProcessedChunkIds:this.renderedChunkIds(),focusedIndex=Math.max(0,previousIds.indexOf(focusedId)),nextChunks=this.errorText?[]:this.processedChunks.chunks;if(nextChunks.length===0){this.pendingFocusTarget="base";return}const survivingIndex=nextChunks.findIndex(chunk=>chunk.id===focusedId),nextIndex=survivingIndex>=0?survivingIndex:Math.min(focusedIndex,nextChunks.length-1);this.pendingFocusTarget=nextChunks[nextIndex].id}updated(changed){super.updated(changed);const wasMounting=this.isMounting;this.isMounting=!1,!wasMounting&&changed.has("errorText")&&this.errorText!==""&&this.isConnected&&(this.initialStateAnnounced=!0,this.errorAnnouncementSink?.announce(this.errorText));const emptyPresented=!this.loading&&this.errorText===""&&this.processedChunks.chunks.length===0;!wasMounting&&!this.wasEmptyPresented&&emptyPresented&&this.isConnected&&(this.initialStateAnnounced=!0,this.emptyAnnouncementSink?.announce(this.localize("chunkInspectorEmpty"))),this.wasEmptyPresented=emptyPresented,this.previousProcessedChunkIds=this.errorText?[]:this.processedChunks.chunks.map(chunk=>chunk.id);const generation=++this.focusRestoreGeneration,target=this.pendingFocusTarget;target!==void 0&&(this.pendingFocusTarget=void 0,this.restoreControlledFocus(target,generation))}announcePresentedState(){if(this.errorText!==""){this.errorAnnouncementSink?.announce(this.errorText);return}!this.loading&&this.processedChunks.chunks.length===0&&this.emptyAnnouncementSink?.announce(this.localize("chunkInspectorEmpty"))}async restoreControlledFocus(target,generation){if(await this.updateComplete,generation!==this.focusRestoreGeneration||!this.isConnected)return;if(target==="base"){this.renderRoot.querySelector('[part="base"]')?.focus();return}const virtualList=this.renderRoot.querySelector(tag("virtual-list"));if(await virtualList?.updateComplete,generation!==this.focusRestoreGeneration||!this.isConnected)return;const roots=[this.renderRoot];virtualList?.shadowRoot&&roots.push(virtualList.shadowRoot);const candidates=roots.flatMap(root=>[...root.querySelectorAll("[data-chunk-id]")]),checkbox=candidates.find(element=>element.localName===tag("checkbox")&&element.getAttribute("data-chunk-id")===target);if(checkbox){checkbox.focus();return}const inspector=candidates.find(element=>element.localName===tag("chunk-inspector")&&element.getAttribute("data-chunk-id")===target);await inspector?.updateComplete,!(generation!==this.focusRestoreGeneration||!this.isConnected)&&inspector?.shadowRoot?.querySelector('[part="open-button"]')?.focus()}get effectiveVirtualizeAt(){return finiteCount(this.virtualizeAt,50)}canonicalChunks(){return firstByRetrievalIdentity(Array.isArray(this.chunks)?this.chunks.filter(isValidRetrievalChunk):[],chunk=>chunk.id)}normalizedSelectedChunkIds(){const validIds=new Set(this.canonicalChunks().map(chunk=>chunk.id));return canonicalIdentityList(this.selectedChunkIds).filter(id=>validIds.has(id))}get processedChunks(){return this.processedChunksCache??=this.computeProcessedChunks()}computeProcessedChunks(){const canonical=this.canonicalChunks(),sorted=this.sort==="score"?canonical.sort((a,b)=>safeScore(b.score)-safeScore(a.score)):canonical;if(this.grouping==="source")return this.bucketed(sorted,chunk=>chunk.source.id,(_id,groupChunks)=>groupChunks[0].source.name||this.localize("untitledSource"));if(this.grouping==="custom"&&this.groupBy){const groupBy=this.groupBy;return this.bucketed(sorted,groupBy,(id,groupChunks)=>this.groupLabel?.(id,groupChunks)??id)}return{chunks:sorted,groups:[]}}orderedGroupKeys(grouped){const firstSeen=[...grouped.keys()];if(this.grouping!=="custom"||!this.groupOrder)return firstSeen;if(typeof this.groupOrder=="function")return firstSeen.sort(this.groupOrder);const ordered=[...new Set(this.groupOrder)].filter(id=>grouped.has(id)),listed=new Set(ordered);return[...ordered,...firstSeen.filter(id=>!listed.has(id))]}bucketed(sorted,keyOf,labelOf){const grouped=new Map;for(const chunk of sorted){const key=keyOf(chunk),existing=grouped.get(key);existing?existing.push(chunk):grouped.set(key,[chunk])}const rows=[],groups=[];for(const key of this.orderedGroupKeys(grouped)){const groupChunks=grouped.get(key);!groupChunks||groupChunks.length===0||(groups.push({key,label:labelOf(key,groupChunks),startIndex:rows.length}),rows.push(...groupChunks))}return{chunks:rows,groups}}reportSelection(chunkIds){const selected=new Set(chunkIds),chunks=this.canonicalChunks().filter(chunk=>selected.has(chunk.id));this.emit("lr-selection-change",{selectedChunkIds:chunkIds,chunks}),this.emit("lr-select",{chunkIds,chunks})}toggleSelect(chunk){const next=new Set(this.normalizedSelectedChunkIds());next.has(chunk.id)?next.delete(chunk.id):next.add(chunk.id),this.selectedChunkIds=[...next],this.reportSelection(this.selectedChunkIds)}rowChunksFor(chunk){let row=this.rowChunks.get(chunk);return row||this.rowChunks.set(chunk,row=[toLyraChunk(chunk)]),row}renderMetadata(metadata){return renderRetrievalMetadata(metadata,this.effectiveLocale,this.localize("valueInvalid"),this.localize("valueTruncated"))}isChunkSelected(id){const source=this.selectedChunkIds;return source.length===0||this.processedChunks.chunks.length<=1?(this.selectedMembership=void 0,source.includes(id)):(this.selectedMembership?.source!==source&&(this.selectedMembership={source,ids:new Set(source)}),this.selectedMembership.ids.has(id))}renderLoadMoreFooter(){return this.hasMore?html`
35
35
  <div part="load-more-row">
36
36
  ${this.loading?html`<lr-spinner part="spinner"></lr-spinner>`:html`<button
37
37
  type="button"
@@ -41,9 +41,9 @@ import{__decorate}from"tslib";import{collectionSupport,writeNormalizedOwnedColle
41
41
  ${this.localize("loadMore")}
42
42
  </button>`}
43
43
  </div>
44
- `:nothing}render(){const label=retrievalSemanticLabel(this,this.label==null?this.localize("chunkInspectorLabel"):this.label),groupRole=retrievalSemanticRole(this,"group");if(this.errorText)return html`<div part="base" tabindex="-1">
44
+ `:nothing}render(){(this.selectedMembership?.source!==this.selectedChunkIds||this.errorText||this.chunks.length<=1)&&(this.selectedMembership=void 0);const label=retrievalSemanticLabel(this,this.label==null?this.localize("chunkInspectorLabel"):this.label),groupRole=retrievalSemanticRole(this,"group");if(this.errorText)return html`<div part="base" tabindex="-1">
45
45
  <div part="error">${this.errorText}</div>
46
- </div>`;const processed=this.processedChunks;if(processed.chunks.length===0)return this.loading?html`<div part="base" tabindex="-1">
46
+ </div>`;const processed=this.processedChunks;if(processed.chunks.length<=1&&(this.selectedMembership=void 0),processed.chunks.length===0)return this.loading?html`<div part="base" tabindex="-1">
47
47
  <lr-spinner part="spinner"></lr-spinner>
48
48
  </div>`:html`<div part="base" tabindex="-1">
49
49
  <lr-empty
@@ -85,4 +85,4 @@ get size():LyraSize|undefined;set size(next:LyraSize|undefined);
85
85
  label?:string;
86
86
  /** JS-only accessible-name override for the tree. A markup `aria-label` names the component
87
87
  * as a whole, so it is not cloned onto the inner tree. */
88
- accessibleLabel:string|null;private expandedIds;private query;private activeId;private pendingFocusIndex;private keyboardFocusGeneration;private normalizedInput?;private normalizedModel?;private announcementSink?;private isMounting;private lastFilterAnnouncement;private get sourceEntries();private get selectedIds();connectedCallback():void;disconnectedCallback():void;private get sourceModel();private allLeafIds;private descendantLeafIds;private normalizedSelectedSourceIds;private checkedState;private matchesQuery;private isFiltering;private visibleRows;protected willUpdate(changed:PropertyValues):void;protected updated(changed:PropertyValues):void;private reportSelection;private commitSelection;private toggleEntry;private stopOwnedEvent;private selectAllTargets;private toggleSelectAll;private focusRowByIndex;private onTreeKeyDown;private renderRow;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-source-picker':LyraSourcePicker;}}
88
+ accessibleLabel:string|null;private expandedIds;private query;private activeId;private pendingFocusIndex;private keyboardFocusGeneration;private normalizedInput?;private normalizedModel?;private announcementSink?;private isMounting;private lastFilterAnnouncement;private get sourceEntries();private get selectedIds();connectedCallback():void;disconnectedCallback():void;private get sourceModel();private allLeafIds;private descendantLeafIds;private normalizedSelectedSourceIds;private checkedState;private isFiltering;private visibleRows;protected willUpdate(changed:PropertyValues):void;protected updated(changed:PropertyValues):void;private reportSelection;private commitSelection;private toggleEntry;private stopOwnedEvent;private selectAllTargets;private toggleSelectAll;private focusRowByIndex;private onTreeKeyDown;private renderRow;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-source-picker':LyraSourcePicker;}}
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport,writeNormalizedOwnedCollection}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isNonBlankIdentity}from"../retrieval-identity.js";import{isRtl}from"../../../internal/rtl.js";import"../../media/file-icon/file-icon.class.js";import"../../forms/input/input.class.js";import"../../forms/checkbox/checkbox.class.js";import"../../overlays/empty/empty.class.js";import{styles}from"./source-picker.styles.js";import{normalizeReflectedOptionalSize,optionalSizeConverter}from"../../../internal/variants.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{shadowFocusTarget}from"../../../internal/active-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LYRA_DEFAULT_selectAllSources,LYRA_DEFAULT_sourcePickerMatches,LYRA_DEFAULT_sourcePickerSelection}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_copy,LYRA_DEFAULT_date,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_fileSizeUnitB,LYRA_DEFAULT_fileSizeUnitGb,LYRA_DEFAULT_fileSizeUnitKb,LYRA_DEFAULT_fileSizeUnitMb,LYRA_DEFAULT_fileSizeUnitTb,LYRA_DEFAULT_loading,LYRA_DEFAULT_map,LYRA_DEFAULT_navigation,LYRA_DEFAULT_noData,LYRA_DEFAULT_noMatches,LYRA_DEFAULT_open,LYRA_DEFAULT_progress,LYRA_DEFAULT_restore,LYRA_DEFAULT_search,LYRA_DEFAULT_select,LYRA_DEFAULT_sourceListDefaultLabel,LYRA_DEFAULT_valueInvalid}from"../../../internal/default-strings/shared.generated.js";const MAX_SOURCE_NODES=2e3,MAX_SOURCE_DEPTH=64,EMPTY_SOURCE_ENTRIES=Object.freeze([]),EMPTY_SOURCE_IDS=Object.freeze([]);class LyraSourcePicker extends LyraElement{constructor(){super(...arguments),this.sources=[],this.selectedSourceIds=[],this.withoutSelectAll=!1,this.withoutSearch=!1,this.accessibleLabel=null,this.expandedIds=new Set,this.query="",this.activeId=null,this.keyboardFocusGeneration=0,this.isMounting=!0,this.lastFilterAnnouncement="",this.stopOwnedEvent=event=>{event.stopPropagation()},this.onTreeKeyDown=e=>{const rows=this.visibleRows();if(rows.length===0)return;const currentIndex=Math.max(0,rows.findIndex(r=>r.entry.id===this.activeId)),current=rows[currentIndex],rtl=isRtl(this),expandKey=rtl?"ArrowLeft":"ArrowRight",collapseKey=rtl?"ArrowRight":"ArrowLeft";switch(e.key){case"ArrowDown":e.preventDefault(),this.focusRowByIndex(Math.min(rows.length-1,currentIndex+1),rows);break;case"ArrowUp":e.preventDefault(),this.focusRowByIndex(Math.max(0,currentIndex-1),rows);break;case"Home":e.preventDefault(),this.focusRowByIndex(0,rows);break;case"End":e.preventDefault(),this.focusRowByIndex(rows.length-1,rows);break;case expandKey:if(e.preventDefault(),current.hasChildren&&!this.expandedIds.has(current.entry.id))this.expandedIds=new Set(this.expandedIds).add(current.entry.id);else if(current.hasChildren){const next=this.visibleRows()[currentIndex+1];next&&next.depth>current.depth&&this.focusRowByIndex(currentIndex+1,this.visibleRows())}break;case collapseKey:if(e.preventDefault(),current.hasChildren&&this.expandedIds.has(current.entry.id)){const set=new Set(this.expandedIds);set.delete(current.entry.id),this.expandedIds=set}else for(let i=currentIndex-1;i>=0;i--)if(rows[i].depth<current.depth){this.focusRowByIndex(i,rows);break}break;case"Enter":case" ":e.preventDefault(),this.toggleEntry(current.entry);break;default:return}}}static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,fileSizeUnitB:LYRA_DEFAULT_fileSizeUnitB,fileSizeUnitGb:LYRA_DEFAULT_fileSizeUnitGb,fileSizeUnitKb:LYRA_DEFAULT_fileSizeUnitKb,fileSizeUnitMb:LYRA_DEFAULT_fileSizeUnitMb,fileSizeUnitTb:LYRA_DEFAULT_fileSizeUnitTb,loading:LYRA_DEFAULT_loading,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,noData:LYRA_DEFAULT_noData,noMatches:LYRA_DEFAULT_noMatches,open:LYRA_DEFAULT_open,progress:LYRA_DEFAULT_progress,restore:LYRA_DEFAULT_restore,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select,selectAllSources:LYRA_DEFAULT_selectAllSources,sourceListDefaultLabel:LYRA_DEFAULT_sourceListDefaultLabel,sourcePickerMatches:LYRA_DEFAULT_sourcePickerMatches,sourcePickerSelection:LYRA_DEFAULT_sourcePickerSelection,valueInvalid:LYRA_DEFAULT_valueInvalid}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["sources","selectedSourceIds"])}static{this.styles=[LyraElement.styles,styles]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change","lr-sources-change"])}get size(){return this._size}set size(next){const normalized=normalizeReflectedOptionalSize(this,next),old=this._size;old!==normalized&&(this._size=normalized,this.requestUpdate("size",old))}get sourceEntries(){return Array.isArray(this.sources)?this.sources:EMPTY_SOURCE_ENTRIES}get selectedIds(){return Array.isArray(this.selectedSourceIds)?this.selectedSourceIds:EMPTY_SOURCE_IDS}connectedCallback(){super.connectedCallback(),this.announcementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.isMounting=!0,this.lastFilterAnnouncement="",this.announcementSink?.release(),this.announcementSink=void 0,super.disconnectedCallback()}get sourceModel(){if(this.normalizedInput===this.sourceEntries&&this.normalizedModel)return this.normalizedModel;const roots=[],nodes=[],byEntry=new WeakMap,seenObjects=new WeakSet,seenIds=new Set;let limited=!1;const stack=[];stack.push({sources:this.sourceEntries,target:roots,depth:0,index:0});let inspected=0;for(;stack.length;){const frame=stack[stack.length-1];if(frame.index>=frame.sources.length){stack.pop();continue}if(inspected>=MAX_SOURCE_NODES){limited=!0;break}const source=frame.sources[frame.index++];if(inspected++,!source||typeof source!="object"||seenObjects.has(source)||!isNonBlankIdentity(source.id)||!isNonBlankIdentity(source.label)||seenIds.has(source.id)){limited=!0;continue}if(nodes.length>=MAX_SOURCE_NODES||frame.depth>MAX_SOURCE_DEPTH){limited=!0;continue}seenObjects.add(source),seenIds.add(source.id);const declaredGroup=Array.isArray(source.children),entry={id:source.id,label:source.label,...source.mimeType!==void 0?{mimeType:source.mimeType}:{},...source.name!==void 0?{name:source.name}:{},...declaredGroup?{children:[]}:{}},node={entry,depth:frame.depth,children:[],leafIds:[]};declaredGroup&&(entry.children=node.children.map(child=>child.entry)),frame.target.push(node),nodes.push(node),byEntry.set(entry,node);const children=Array.isArray(source.children)?source.children:[];children.length&&frame.depth>=MAX_SOURCE_DEPTH&&(limited=!0),children.length&&frame.depth<MAX_SOURCE_DEPTH&&stack.push({sources:children,target:node.children,depth:frame.depth+1,index:0})}for(let index=nodes.length-1;index>=0;index--){const node=nodes[index];node.entry.children!==void 0&&(node.entry.children=node.children.map(child=>child.entry)),node.leafIds=node.entry.children===void 0?[node.entry.id]:[...new Set(node.children.flatMap(child=>child.leafIds))]}const leafIds=[...new Set(roots.flatMap(root=>root.leafIds))];return this.normalizedInput=this.sourceEntries,this.normalizedModel={roots,nodes,byEntry,leafIds,limited},this.normalizedModel}allLeafIds(){return this.sourceModel.leafIds}descendantLeafIds(entry){return this.sourceModel.byEntry.get(entry)?.leafIds??[]}normalizedSelectedSourceIds(){const valid=new Set(this.allLeafIds()),seen=new Set;return this.selectedIds.filter(id=>!valid.has(id)||seen.has(id)?!1:(seen.add(id),!0))}checkedState(entry,selectedIds){const leaves=this.descendantLeafIds(entry),selected=leaves.filter(id=>selectedIds.has(id));return selected.length===0?"false":selected.length===leaves.length?"true":"mixed"}matchesQuery(entry){return entry.label.toLocaleLowerCase(this.effectiveLocale).includes(this.query.trim().toLocaleLowerCase(this.effectiveLocale))}isFiltering(){return!this.withoutSearch&&this.query.trim().length>0}visibleRows(){const rows=[],filtering=this.isFiltering(),matches=new Set;if(filtering)for(let index=this.sourceModel.nodes.length-1;index>=0;index--){const node=this.sourceModel.nodes[index];(this.matchesQuery(node.entry)||node.children.some(child=>matches.has(child)))&&matches.add(node)}const stack=[...this.sourceModel.roots].reverse();for(;stack.length;){const node=stack.pop();if(filtering&&!matches.has(node))continue;const hasChildren=node.entry.children!==void 0;if(rows.push({entry:node.entry,depth:node.depth,hasChildren}),hasChildren&&(filtering||this.expandedIds.has(node.entry.id)))for(let index=node.children.length-1;index>=0;index--)stack.push(node.children[index])}return rows}willUpdate(changed){if(super.willUpdate(changed),changed.has("sources")||changed.has("selectedSourceIds")){const normalized=this.normalizedSelectedSourceIds(),current=this.selectedIds;if(normalized.length!==current.length||normalized.some((id,index)=>id!==current[index])){const shouldAnnounce=this.hasUpdated&&changed.has("sources");writeNormalizedOwnedCollection(this,"selectedSourceIds",()=>{this.selectedSourceIds=normalized}),shouldAnnounce&&this.reportSelection(normalized)}}if(!changed.has("sources")&&!changed.has("query")&&!changed.has("expandedIds")&&!changed.has("withoutSearch"))return;const focusedIndex=Array.from(this.renderRoot.querySelectorAll('[part~="item"]')).indexOf(shadowFocusTarget(this)),rows=this.visibleRows(),retainedIndex=rows.findIndex(row=>row.entry.id===this.activeId),nextIndex=retainedIndex>=0?retainedIndex:rows.length?Math.min(Math.max(focusedIndex,0),rows.length-1):-1;this.activeId=nextIndex>=0?rows[nextIndex].entry.id:null,focusedIndex>=0&&(this.pendingFocusIndex=nextIndex>=0?nextIndex:this.sourceEntries.length===0||this.withoutSearch?"base":"search")}updated(changed){super.updated(changed);const pending=this.pendingFocusIndex;pending!==void 0&&(this.pendingFocusIndex=void 0,pending==="search"?this.renderRoot.querySelector('[part~="search"]')?.focus():pending==="base"?this.renderRoot.querySelector('[part="base"]')?.focus():this.renderRoot.querySelectorAll('[part~="item"]')[pending]?.focus());const wasMounting=this.isMounting;if(this.isMounting=!1,wasMounting||!changed.has("query")&&!changed.has("sources"))return;if(!this.isFiltering()){this.lastFilterAnnouncement="";return}const count=this.visibleRows().filter(row=>this.matchesQuery(row.entry)).length,signature=`${this.query.trim().toLocaleLowerCase(this.effectiveLocale)}\0${count}`;signature!==this.lastFilterAnnouncement&&(this.lastFilterAnnouncement=signature,this.announcementSink?.announce(count===0?this.localize("noMatches"):this.localize("sourcePickerMatches",void 0,{count:getNumberFormat(this.effectiveLocale).format(count),pluralCount:count})))}reportSelection(selectedSourceIds){this.emit("lr-selection-change",{selectedSourceIds}),this.emit("lr-sources-change",{selectedSourceIds})}commitSelection(next){this.selectedSourceIds=next,this.reportSelection(next)}toggleEntry(entry){const leaves=this.descendantLeafIds(entry),set=new Set(this.normalizedSelectedSourceIds()),willSelect=this.checkedState(entry,set)!=="true";for(const id of leaves)willSelect?set.add(id):set.delete(id);this.commitSelection([...set])}selectAllTargets(rows){return this.isFiltering()?rows.filter(row=>!row.hasChildren).map(row=>row.entry.id):this.allLeafIds()}toggleSelectAll(){const targets=this.selectAllTargets(this.visibleRows());if(!targets.length)return;const selected=new Set(this.normalizedSelectedSourceIds()),allSelected=targets.every(id=>selected.has(id));for(const id of targets)allSelected?selected.delete(id):selected.add(id);this.commitSelection([...selected])}focusRowByIndex(index,rows){const targetId=rows[index]?.entry.id;if(!targetId)return;this.activeId=targetId;const generation=++this.keyboardFocusGeneration;this.updateComplete.then(()=>{if(!this.isConnected||generation!==this.keyboardFocusGeneration)return;const currentIndex=this.visibleRows().findIndex(row=>row.entry.id===targetId);if(currentIndex<0)return;this.renderRoot.querySelectorAll('[part~="item"]')[currentIndex]?.focus()})}renderRow(row,active,selectedIds){const state2=this.checkedState(row.entry,selectedIds),expanded=row.hasChildren&&(this.expandedIds.has(row.entry.id)||this.isFiltering());return html`
1
+ import{__decorate}from"tslib";import{collectionSupport,writeNormalizedOwnedCollection}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isNonBlankIdentity}from"../retrieval-identity.js";import{isRtl}from"../../../internal/rtl.js";import"../../media/file-icon/file-icon.class.js";import"../../forms/input/input.class.js";import"../../forms/checkbox/checkbox.class.js";import"../../overlays/empty/empty.class.js";import{styles}from"./source-picker.styles.js";import{normalizeReflectedOptionalSize,optionalSizeConverter}from"../../../internal/variants.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{shadowFocusTarget}from"../../../internal/active-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LYRA_DEFAULT_selectAllSources,LYRA_DEFAULT_sourcePickerMatches,LYRA_DEFAULT_sourcePickerSelection}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_copy,LYRA_DEFAULT_date,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_fileSizeUnitB,LYRA_DEFAULT_fileSizeUnitGb,LYRA_DEFAULT_fileSizeUnitKb,LYRA_DEFAULT_fileSizeUnitMb,LYRA_DEFAULT_fileSizeUnitTb,LYRA_DEFAULT_loading,LYRA_DEFAULT_map,LYRA_DEFAULT_navigation,LYRA_DEFAULT_noData,LYRA_DEFAULT_noMatches,LYRA_DEFAULT_open,LYRA_DEFAULT_progress,LYRA_DEFAULT_restore,LYRA_DEFAULT_search,LYRA_DEFAULT_select,LYRA_DEFAULT_sourceListDefaultLabel,LYRA_DEFAULT_valueInvalid}from"../../../internal/default-strings/shared.generated.js";const MAX_SOURCE_NODES=2e3,MAX_SOURCE_DEPTH=64,EMPTY_SOURCE_ENTRIES=Object.freeze([]),EMPTY_SOURCE_IDS=Object.freeze([]);class LyraSourcePicker extends LyraElement{constructor(){super(...arguments),this.sources=[],this.selectedSourceIds=[],this.withoutSelectAll=!1,this.withoutSearch=!1,this.accessibleLabel=null,this.expandedIds=new Set,this.query="",this.activeId=null,this.keyboardFocusGeneration=0,this.isMounting=!0,this.lastFilterAnnouncement="",this.stopOwnedEvent=event=>{event.stopPropagation()},this.onTreeKeyDown=e=>{const rows=this.visibleRows();if(rows.length===0)return;const currentIndex=Math.max(0,rows.findIndex(r=>r.entry.id===this.activeId)),current=rows[currentIndex],rtl=isRtl(this),expandKey=rtl?"ArrowLeft":"ArrowRight",collapseKey=rtl?"ArrowRight":"ArrowLeft";switch(e.key){case"ArrowDown":e.preventDefault(),this.focusRowByIndex(Math.min(rows.length-1,currentIndex+1),rows);break;case"ArrowUp":e.preventDefault(),this.focusRowByIndex(Math.max(0,currentIndex-1),rows);break;case"Home":e.preventDefault(),this.focusRowByIndex(0,rows);break;case"End":e.preventDefault(),this.focusRowByIndex(rows.length-1,rows);break;case expandKey:if(e.preventDefault(),current.hasChildren&&!this.expandedIds.has(current.entry.id))this.expandedIds=new Set(this.expandedIds).add(current.entry.id);else if(current.hasChildren){const next=this.visibleRows()[currentIndex+1];next&&next.depth>current.depth&&this.focusRowByIndex(currentIndex+1,this.visibleRows())}break;case collapseKey:if(e.preventDefault(),current.hasChildren&&this.expandedIds.has(current.entry.id)){const set=new Set(this.expandedIds);set.delete(current.entry.id),this.expandedIds=set}else for(let i=currentIndex-1;i>=0;i--)if(rows[i].depth<current.depth){this.focusRowByIndex(i,rows);break}break;case"Enter":case" ":e.preventDefault(),this.toggleEntry(current.entry);break;default:return}}}static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,fileSizeUnitB:LYRA_DEFAULT_fileSizeUnitB,fileSizeUnitGb:LYRA_DEFAULT_fileSizeUnitGb,fileSizeUnitKb:LYRA_DEFAULT_fileSizeUnitKb,fileSizeUnitMb:LYRA_DEFAULT_fileSizeUnitMb,fileSizeUnitTb:LYRA_DEFAULT_fileSizeUnitTb,loading:LYRA_DEFAULT_loading,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,noData:LYRA_DEFAULT_noData,noMatches:LYRA_DEFAULT_noMatches,open:LYRA_DEFAULT_open,progress:LYRA_DEFAULT_progress,restore:LYRA_DEFAULT_restore,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select,selectAllSources:LYRA_DEFAULT_selectAllSources,sourceListDefaultLabel:LYRA_DEFAULT_sourceListDefaultLabel,sourcePickerMatches:LYRA_DEFAULT_sourcePickerMatches,sourcePickerSelection:LYRA_DEFAULT_sourcePickerSelection,valueInvalid:LYRA_DEFAULT_valueInvalid}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["sources","selectedSourceIds"])}static{this.styles=[LyraElement.styles,styles]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change","lr-sources-change"])}get size(){return this._size}set size(next){const normalized=normalizeReflectedOptionalSize(this,next),old=this._size;old!==normalized&&(this._size=normalized,this.requestUpdate("size",old))}get sourceEntries(){return Array.isArray(this.sources)?this.sources:EMPTY_SOURCE_ENTRIES}get selectedIds(){return Array.isArray(this.selectedSourceIds)?this.selectedSourceIds:EMPTY_SOURCE_IDS}connectedCallback(){super.connectedCallback(),this.announcementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.isMounting=!0,this.lastFilterAnnouncement="",this.announcementSink?.release(),this.announcementSink=void 0,super.disconnectedCallback()}get sourceModel(){if(this.normalizedInput===this.sourceEntries&&this.normalizedModel)return this.normalizedModel;const roots=[],nodes=[],byEntry=new WeakMap,seenObjects=new WeakSet,seenIds=new Set;let limited=!1;const stack=[];stack.push({sources:this.sourceEntries,target:roots,depth:0,index:0});let inspected=0;for(;stack.length;){const frame=stack[stack.length-1];if(frame.index>=frame.sources.length){stack.pop();continue}if(inspected>=MAX_SOURCE_NODES){limited=!0;break}const source=frame.sources[frame.index++];if(inspected++,!source||typeof source!="object"||seenObjects.has(source)||!isNonBlankIdentity(source.id)||!isNonBlankIdentity(source.label)||seenIds.has(source.id)){limited=!0;continue}if(nodes.length>=MAX_SOURCE_NODES||frame.depth>MAX_SOURCE_DEPTH){limited=!0;continue}seenObjects.add(source),seenIds.add(source.id);const declaredGroup=Array.isArray(source.children),entry={id:source.id,label:source.label,...source.mimeType!==void 0?{mimeType:source.mimeType}:{},...source.name!==void 0?{name:source.name}:{},...declaredGroup?{children:[]}:{}},node={entry,depth:frame.depth,children:[],leafIds:[]};declaredGroup&&(entry.children=node.children.map(child=>child.entry)),frame.target.push(node),nodes.push(node),byEntry.set(entry,node);const children=Array.isArray(source.children)?source.children:[];children.length&&frame.depth>=MAX_SOURCE_DEPTH&&(limited=!0),children.length&&frame.depth<MAX_SOURCE_DEPTH&&stack.push({sources:children,target:node.children,depth:frame.depth+1,index:0})}for(let index=nodes.length-1;index>=0;index--){const node=nodes[index];node.entry.children!==void 0&&(node.entry.children=node.children.map(child=>child.entry)),node.leafIds=node.entry.children===void 0?[node.entry.id]:[...new Set(node.children.flatMap(child=>child.leafIds))]}const leafIds=[...new Set(roots.flatMap(root=>root.leafIds))];return this.normalizedInput=this.sourceEntries,this.normalizedModel={roots,nodes,byEntry,leafIds,limited},this.normalizedModel}allLeafIds(){return this.sourceModel.leafIds}descendantLeafIds(entry){return this.sourceModel.byEntry.get(entry)?.leafIds??[]}normalizedSelectedSourceIds(){const valid=new Set(this.allLeafIds()),seen=new Set;return this.selectedIds.filter(id=>!valid.has(id)||seen.has(id)?!1:(seen.add(id),!0))}checkedState(entry,selectedIds){const leaves=this.descendantLeafIds(entry),selected=leaves.filter(id=>selectedIds.has(id));return selected.length===0?"false":selected.length===leaves.length?"true":"mixed"}isFiltering(){return!this.withoutSearch&&this.query.trim().length>0}visibleRows(){const rows=[],filtering=this.isFiltering(),matches=new Set;if(filtering){const locale=this.effectiveLocale,query=this.query.trim().toLocaleLowerCase(locale);for(let index=this.sourceModel.nodes.length-1;index>=0;index--){const node=this.sourceModel.nodes[index];(node.entry.label.toLocaleLowerCase(locale).includes(query)||node.children.some(child=>matches.has(child)))&&matches.add(node)}}const stack=[...this.sourceModel.roots].reverse();for(;stack.length;){const node=stack.pop();if(filtering&&!matches.has(node))continue;const hasChildren=node.entry.children!==void 0;if(rows.push({entry:node.entry,depth:node.depth,hasChildren}),hasChildren&&(filtering||this.expandedIds.has(node.entry.id)))for(let index=node.children.length-1;index>=0;index--)stack.push(node.children[index])}return rows}willUpdate(changed){if(super.willUpdate(changed),changed.has("sources")||changed.has("selectedSourceIds")){const normalized=this.normalizedSelectedSourceIds(),current=this.selectedIds;if(normalized.length!==current.length||normalized.some((id,index)=>id!==current[index])){const shouldAnnounce=this.hasUpdated&&changed.has("sources");writeNormalizedOwnedCollection(this,"selectedSourceIds",()=>{this.selectedSourceIds=normalized}),shouldAnnounce&&this.reportSelection(normalized)}}if(!changed.has("sources")&&!changed.has("query")&&!changed.has("expandedIds")&&!changed.has("withoutSearch"))return;const focusedIndex=Array.from(this.renderRoot.querySelectorAll('[part~="item"]')).indexOf(shadowFocusTarget(this)),rows=this.visibleRows(),retainedIndex=rows.findIndex(row=>row.entry.id===this.activeId),nextIndex=retainedIndex>=0?retainedIndex:rows.length?Math.min(Math.max(focusedIndex,0),rows.length-1):-1;this.activeId=nextIndex>=0?rows[nextIndex].entry.id:null,focusedIndex>=0&&(this.pendingFocusIndex=nextIndex>=0?nextIndex:this.sourceEntries.length===0||this.withoutSearch?"base":"search")}updated(changed){super.updated(changed);const pending=this.pendingFocusIndex;pending!==void 0&&(this.pendingFocusIndex=void 0,pending==="search"?this.renderRoot.querySelector('[part~="search"]')?.focus():pending==="base"?this.renderRoot.querySelector('[part="base"]')?.focus():this.renderRoot.querySelectorAll('[part~="item"]')[pending]?.focus());const wasMounting=this.isMounting;if(this.isMounting=!1,wasMounting||!changed.has("query")&&!changed.has("sources"))return;if(!this.isFiltering()){this.lastFilterAnnouncement="";return}const locale=this.effectiveLocale,query=this.query.trim().toLocaleLowerCase(locale),count=this.visibleRows().filter(row=>row.entry.label.toLocaleLowerCase(locale).includes(query)).length,signature=`${query}\0${count}`;signature!==this.lastFilterAnnouncement&&(this.lastFilterAnnouncement=signature,this.announcementSink?.announce(count===0?this.localize("noMatches"):this.localize("sourcePickerMatches",void 0,{count:getNumberFormat(locale).format(count),pluralCount:count})))}reportSelection(selectedSourceIds){this.emit("lr-selection-change",{selectedSourceIds}),this.emit("lr-sources-change",{selectedSourceIds})}commitSelection(next){this.selectedSourceIds=next,this.reportSelection(next)}toggleEntry(entry){const leaves=this.descendantLeafIds(entry),set=new Set(this.normalizedSelectedSourceIds()),willSelect=this.checkedState(entry,set)!=="true";for(const id of leaves)willSelect?set.add(id):set.delete(id);this.commitSelection([...set])}selectAllTargets(rows){return this.isFiltering()?rows.filter(row=>!row.hasChildren).map(row=>row.entry.id):this.allLeafIds()}toggleSelectAll(){const targets=this.selectAllTargets(this.visibleRows());if(!targets.length)return;const selected=new Set(this.normalizedSelectedSourceIds()),allSelected=targets.every(id=>selected.has(id));for(const id of targets)allSelected?selected.delete(id):selected.add(id);this.commitSelection([...selected])}focusRowByIndex(index,rows){const targetId=rows[index]?.entry.id;if(!targetId)return;this.activeId=targetId;const generation=++this.keyboardFocusGeneration;this.updateComplete.then(()=>{if(!this.isConnected||generation!==this.keyboardFocusGeneration)return;const currentIndex=this.visibleRows().findIndex(row=>row.entry.id===targetId);if(currentIndex<0)return;this.renderRoot.querySelectorAll('[part~="item"]')[currentIndex]?.focus()})}renderRow(row,active,selectedIds){const state2=this.checkedState(row.entry,selectedIds),expanded=row.hasChildren&&(this.expandedIds.has(row.entry.id)||this.isFiltering());return html`
2
2
  <div
3
3
  part="item"
4
4
  role="treeitem"
@@ -1,6 +1,6 @@
1
1
  import{__decorate}from"tslib";import{eventCollectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{unsafeHTML}from"lit/directives/unsafe-html.js";import{srOnly}from"../../../internal/a11y.js";import{LyraElement}from"../../../internal/lyra-element.js";import{TextViewerTarget}from"../../../internal/text-viewer-target.js";import{createTextQuoteIndex,scopeFromElement,TEXT_QUOTE_LIMITS}from"../../../internal/text-quote.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getDateTimeFormat,getListFormat,getNumberFormat}from"../../../internal/intl-cache.js";import{formatFileSize,FILE_SIZE_UNIT_KEYS}from"../../media/attachment-chip/file-size.js";import{loadEmailDeps}from"./email-loader.js";import{styles}from"./email-viewer.styles.js";import{viewerFrameStyles}from"../viewer-frame.js";import{sanitizeCssLength}from"../../../internal/safe-css.js";import{shadowFocusTarget}from"../../../internal/active-element.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{renderViewerLoading,viewerLoadingStyles}from"../viewer-loading.js";import{sanitizePassiveMarkup}from"../passive-markup.js";import{viewerSemanticLabel,viewerSemanticRole}from"../viewer-semantic-owner.js";import{DeferredTeardown}from"../document-viewer/deferred-teardown.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_copy,LYRA_DEFAULT_date,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_download,LYRA_DEFAULT_fileSizeUnitB,LYRA_DEFAULT_fileSizeUnitGb,LYRA_DEFAULT_fileSizeUnitKb,LYRA_DEFAULT_fileSizeUnitMb,LYRA_DEFAULT_fileSizeUnitTb,LYRA_DEFAULT_loading,LYRA_DEFAULT_map,LYRA_DEFAULT_navigation,LYRA_DEFAULT_open,LYRA_DEFAULT_popover,LYRA_DEFAULT_search,LYRA_DEFAULT_select}from"../../../internal/default-strings/shared.generated.js";import{LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeEmail,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_documentViewerMissingSanitizer,LYRA_DEFAULT_emailViewerAttachments,LYRA_DEFAULT_emailViewerDate,LYRA_DEFAULT_emailViewerFrom,LYRA_DEFAULT_emailViewerGroupAddress,LYRA_DEFAULT_emailViewerHideQuoted,LYRA_DEFAULT_emailViewerLabel,LYRA_DEFAULT_emailViewerMissingParser,LYRA_DEFAULT_emailViewerNoSubject,LYRA_DEFAULT_emailViewerOpenAttachment,LYRA_DEFAULT_emailViewerShowQuoted,LYRA_DEFAULT_emailViewerSubject,LYRA_DEFAULT_emailViewerTo,LYRA_DEFAULT_emailViewerUnnamedAttachment,LYRA_DEFAULT_loadingDocument}from"../../../internal/default-strings/viewers.generated.js";const MAX_EMAIL_RECIPIENT_POSITIONS=1e4,MAX_EMAIL_RECIPIENT_DEPTH=100,MAX_EMAIL_ATTACHMENT_POSITIONS=1e4;function isArrayValue(value){try{return Array.isArray(value)}catch{return!1}}function isSafeRecord(value){if(value===null||typeof value!="object"||isArrayValue(value))return!1;try{const prototype=Object.getPrototypeOf(value);return prototype===null||Object.getPrototypeOf(prototype)===null}catch{return!1}}function optionalOwnString(value,key){const descriptor=getOwnDataDescriptor(value,key);return descriptor!==MISSING_OWN_DATA_DESCRIPTOR&&descriptor!==UNSAFE_OWN_DATA_DESCRIPTOR&&typeof descriptor.value=="string"?descriptor.value:void 0}function optionalOwnValue(value,key){const descriptor=getOwnDataDescriptor(value,key);return descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR?void 0:descriptor.value}function projectAddressList(value,budget,depth){if(!isArrayValue(value)||budget.positions>=MAX_EMAIL_RECIPIENT_POSITIONS)return[];const length=getOwnDataDescriptor(value,"length");if(length===MISSING_OWN_DATA_DESCRIPTOR||length===UNSAFE_OWN_DATA_DESCRIPTOR||typeof length.value!="number"||!Number.isSafeInteger(length.value)||length.value<0)return[];const addresses=[],count=Math.min(length.value,MAX_EMAIL_RECIPIENT_POSITIONS-budget.positions);for(let index=0;index<count;index+=1){budget.positions+=1;const descriptor=getOwnDataDescriptor(value,String(index));if(descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR)continue;const address=projectAddress(descriptor.value,budget,depth);address&&addresses.push(address)}return addresses}function projectAddress(value,budget,depth){if(depth>MAX_EMAIL_RECIPIENT_DEPTH||budget.nodes>=MAX_EMAIL_RECIPIENT_POSITIONS||!isSafeRecord(value)||budget.seen.has(value))return;budget.seen.add(value),budget.nodes+=1;const name=optionalOwnString(value,"name"),address=optionalOwnString(value,"address"),groupValue=optionalOwnValue(value,"group"),group=groupValue===void 0?[]:projectAddressList(groupValue,budget,depth+1);if(!(name===void 0&&address===void 0&&group.length===0))return Object.freeze({...name===void 0?{}:{name},...address===void 0?{}:{address},...group.length===0?{}:{group:Object.freeze(group)}})}function normalizeAttachmentContent(content){try{if(typeof content=="string")return new TextEncoder().encode(content);if(content instanceof Uint8Array)return new Uint8Array(content);if(content instanceof ArrayBuffer)return new Uint8Array(content.slice(0))}catch{return}}function projectAttachments(value){if(!isArrayValue(value))return Object.freeze([]);const length=getOwnDataDescriptor(value,"length");if(length===MISSING_OWN_DATA_DESCRIPTOR||length===UNSAFE_OWN_DATA_DESCRIPTOR||typeof length.value!="number"||!Number.isSafeInteger(length.value)||length.value<0)return Object.freeze([]);const attachments=[],count=Math.min(length.value,MAX_EMAIL_ATTACHMENT_POSITIONS);for(let index=0;index<count;index+=1){const entry=getOwnDataDescriptor(value,String(index));if(entry===MISSING_OWN_DATA_DESCRIPTOR||entry===UNSAFE_OWN_DATA_DESCRIPTOR||!isSafeRecord(entry.value))continue;const content=normalizeAttachmentContent(optionalOwnValue(entry.value,"content"));if(!content)continue;const filename=optionalOwnString(entry.value,"filename")??"",mimeType=optionalOwnString(entry.value,"mimeType")??"";attachments.push(Object.freeze({filename,mimeType,size:content.byteLength,content}))}return Object.freeze(attachments)}function normalizeParsedEmail(value){if(!isSafeRecord(value))return null;const budget={positions:0,nodes:0,seen:new WeakSet},htmlValue=optionalOwnValue(value,"html"),textValue=optionalOwnValue(value,"text"),subjectValue=optionalOwnValue(value,"subject"),dateValue=optionalOwnValue(value,"date"),html2=typeof htmlValue=="string"?htmlValue:void 0,text=typeof textValue=="string"?textValue:void 0,subject=typeof subjectValue=="string"?subjectValue:void 0,date=typeof dateValue=="string"?dateValue:void 0,from=projectAddress(optionalOwnValue(value,"from"),budget,0),to=projectAddressList(optionalOwnValue(value,"to"),budget,0);return Object.freeze({...html2===void 0?{}:{html:html2},...text===void 0?{}:{text},...from===void 0?{}:{from},to:Object.freeze(to),...subject===void 0?{}:{subject},...date===void 0?{}:{date},attachments:projectAttachments(optionalOwnValue(value,"attachments"))})}function immutableAttachmentBlob(content,mimeType){const copied=new Uint8Array(content.byteLength);return copied.set(content),new Blob([copied],{type:mimeType})}class LyraEmailViewerBase extends LyraElement{static{this.collectionSupport=eventCollectionSupport}static{this.immutableEventDetails=Object.freeze(["lr-attachment-open","lr-text-select"])}}function splitTrailingQuoteBlock(text){const lines=text.split(/\r\n|\r|\n/);let start=lines.length,quotedLineCount=0;for(let i=lines.length-1;i>=0;i--)if(lines[i].trimStart().startsWith(">"))start=i,quotedLineCount++;else if(lines[i].trim()==="")start=i;else break;return quotedLineCount<3?null:{visible:lines.slice(0,start).join(`
2
2
  `),quoted:lines.slice(start).join(`
3
- `)}}const QUOTE_SELECTOR='blockquote[type="cite" i], div.gmail_quote, div.yahoo_quoted, div[id^="divRplyFwdMsg"]';function parseHtmlDocument(html2,ownerDocument){const DOMParserCtor=ownerDocument.defaultView?.DOMParser;return DOMParserCtor?new DOMParserCtor().parseFromString(html2,"text/html"):null}function foldHtmlQuotes(html2,localize,expandedIndices,ownerDocument){const doc=parseHtmlDocument(html2,ownerDocument);if(!doc)return html2;for(const forged of doc.body.querySelectorAll("[data-quote-toggle], [data-quote-index], [data-email-chrome]"))forged.removeAttribute("data-quote-toggle"),forged.removeAttribute("data-quote-index"),forged.removeAttribute("data-email-chrome");return doc.body.querySelectorAll(QUOTE_SELECTOR).forEach((block,index)=>{const expanded=expandedIndices.includes(index);block.setAttribute("part","quoted"),expanded||block.setAttribute("hidden",""),block.setAttribute("data-quote-index",String(index));const button=doc.createElement("button");button.type="button",button.setAttribute("part","quote-toggle"),button.setAttribute("data-email-chrome","quote-toggle"),button.setAttribute("aria-expanded",String(expanded)),button.setAttribute("data-quote-toggle",String(index)),button.textContent=localize(expanded?"emailViewerHideQuoted":"emailViewerShowQuoted"),block.before(button)}),doc.body.innerHTML}function isQuoteToggleElement(target){const candidate=target;return candidate.nodeType===1&&candidate.localName==="button"&&candidate.hasAttribute("data-quote-toggle")}class LyraEmailViewer extends TextViewerTarget(LyraEmailViewerBase){constructor(){super(...arguments),this.src="",this.name="",this.maxHeight="",this.foldQuotes=!1,this.fetchState={kind:"idle"},this.textQuoteExpanded=!1,this.expandedHtmlQuoteIndices=[],this.generation=0,this.lastLoadSrc="",this.announcements=new ViewerAnnouncementController(this),this.foldedHtmlCache=null,this.detached=new DeferredTeardown(()=>{this.generation++,this.textQuoteExpanded=!1,this.expandedHtmlQuoteIndices=[],this.foldedHtmlCache=null}),this.onBodyClick=e=>{const target=e.composedPath().find(isQuoteToggleElement);if(!target)return;const index=target.getAttribute("data-quote-toggle"),block=this.renderRoot.querySelector(`[data-quote-index="${index}"]`),numericIndex=Number(index);if(!block||!Number.isInteger(numericIndex)||numericIndex<0)return;const restoreFocus=shadowFocusTarget(this)===target;this.expandedHtmlQuoteIndices=this.expandedHtmlQuoteIndices.includes(numericIndex)?this.expandedHtmlQuoteIndices.filter(value=>value!==numericIndex):[...this.expandedHtmlQuoteIndices,numericIndex],restoreFocus&&this.scheduleAfterUpdate(()=>{this.renderRoot.querySelector(`[data-quote-toggle="${numericIndex}"]`)?.focus()})}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeEmail:LYRA_DEFAULT_documentPreviewTypeEmail,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,documentViewerMissingSanitizer:LYRA_DEFAULT_documentViewerMissingSanitizer,download:LYRA_DEFAULT_download,emailViewerAttachments:LYRA_DEFAULT_emailViewerAttachments,emailViewerDate:LYRA_DEFAULT_emailViewerDate,emailViewerFrom:LYRA_DEFAULT_emailViewerFrom,emailViewerGroupAddress:LYRA_DEFAULT_emailViewerGroupAddress,emailViewerHideQuoted:LYRA_DEFAULT_emailViewerHideQuoted,emailViewerLabel:LYRA_DEFAULT_emailViewerLabel,emailViewerMissingParser:LYRA_DEFAULT_emailViewerMissingParser,emailViewerNoSubject:LYRA_DEFAULT_emailViewerNoSubject,emailViewerOpenAttachment:LYRA_DEFAULT_emailViewerOpenAttachment,emailViewerShowQuoted:LYRA_DEFAULT_emailViewerShowQuoted,emailViewerSubject:LYRA_DEFAULT_emailViewerSubject,emailViewerTo:LYRA_DEFAULT_emailViewerTo,emailViewerUnnamedAttachment:LYRA_DEFAULT_emailViewerUnnamedAttachment,fileSizeUnitB:LYRA_DEFAULT_fileSizeUnitB,fileSizeUnitGb:LYRA_DEFAULT_fileSizeUnitGb,fileSizeUnitKb:LYRA_DEFAULT_fileSizeUnitKb,fileSizeUnitMb:LYRA_DEFAULT_fileSizeUnitMb,fileSizeUnitTb:LYRA_DEFAULT_fileSizeUnitTb,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,open:LYRA_DEFAULT_open,popover:LYRA_DEFAULT_popover,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select}}static{this.styles=[LyraElement.styles,styles,viewerFrameStyles,srOnly,viewerLoadingStyles]}async search(query){if(this.foldQuotes&&this.fetchState.kind==="loaded"&&query.trim()&&query.length<=TEXT_QUOTE_LIMITS.maxQueryCodeUnits){const budget={remainingCodeUnits:TEXT_QUOTE_LIMITS.maxSearchWorkCodeUnits},matchesQuote=block=>createTextQuoteIndex(scopeFromElement(block),this.effectiveLocale).search(query,budget).length>0,{bodyHtml,bodyText}=this.fetchState.email;if(bodyHtml!==null){this.searchDocument?.html!==bodyHtml&&(this.searchDocument={html:bodyHtml,doc:parseHtmlDocument(bodyHtml,this.ownerDocument)});const next=new Set(this.expandedHtmlQuoteIndices);this.searchDocument.doc?.body.querySelectorAll(QUOTE_SELECTOR).forEach((block,index)=>{!next.has(index)&&matchesQuote(block)&&next.add(index)});const expanded=[...next];(expanded.length!==this.expandedHtmlQuoteIndices.length||expanded.some((value,index)=>value!==this.expandedHtmlQuoteIndices[index]))&&(this.expandedHtmlQuoteIndices=expanded,await this.updateComplete)}else if(bodyText!==null){const split=splitTrailingQuoteBlock(bodyText),quote=this.ownerDocument.createElement("pre");quote.textContent=split?.quoted??"",split&&!this.textQuoteExpanded&&matchesQuote(quote)&&(this.textQuoteExpanded=!0,await this.updateComplete)}}return super.search(query)}async searchNext(){return super.searchNext()}async searchPrevious(){return super.searchPrevious()}clearSearch(){super.clearSearch()}textContentRoot(){return this.renderRoot.querySelector('[part="body"]')}buildTextScope(root){return scopeFromElement(root,void 0,element=>this.foldQuotes&&element.localName==="button"&&element.getAttribute("data-email-chrome")==="quote-toggle")}connectedCallback(){super.connectedCallback(),this.announcements.connect(),!this.detached.cancel()&&this.hasUpdated&&this.src.trim()&&this.src===this.lastLoadSrc&&this.scheduleAfterUpdate(()=>{this.load()})}disconnectedCallback(){this.announcements.disconnect(),super.disconnectedCallback(),this.detached.schedule()}adoptedCallback(){super.adoptedCallback(),this.detached.flush(),this.announcements.adopted()}willUpdate(changed){super.willUpdate(changed),(changed.has("src")||changed.has("foldQuotes"))&&(this.textQuoteExpanded=!1,this.expandedHtmlQuoteIndices=[])}updated(changed){super.updated(changed),this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument")),changed.has("src")&&this.scheduleAfterUpdate(()=>{this.load()})}async load(){const generation=++this.generation,signal=this.beginAbortableLoad();if(this.lastLoadSrc=this.src,!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){this.failWithLocalizedMessage(this.localize("documentPreviewUrlNotAllowed"));return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isCurrentLoad(generation,fetchTarget.view))return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const buffer=await readResponseArrayBuffer(response);if(!this.isCurrentLoad(generation,fetchTarget.view))return;const result=await this.parse(buffer,generation,fetchTarget.view);result&&this.isCurrentLoad(generation,fetchTarget.view)&&(this.fetchState={kind:"loaded",...result})}catch(error){if(isAbortError(error)||!this.isCurrentLoad(generation,fetchTarget.view))return;this.fetchState={kind:"error",message:error instanceof LyraUserFacingError?error.message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")},this.emit("lr-render-error",{error})}}failWithLocalizedMessage(message){const error=new LyraUserFacingError(message);this.fetchState={kind:"error",message},this.emit("lr-render-error",{error})}isCurrentLoad(generation,ownerView){return this.isConnected&&generation===this.generation&&this.ownerDocument.defaultView===ownerView}async parse(buffer,generation,ownerView){const{PostalMime,DOMPurify}=await loadEmailDeps();if(!this.isCurrentLoad(generation,ownerView))return null;if(!PostalMime)throw new LyraUserFacingError(this.localize("emailViewerMissingParser"));const rawParsed=await PostalMime.parse(buffer);if(!this.isCurrentLoad(generation,ownerView))return null;const parsed=normalizeParsedEmail(rawParsed);if(!parsed)throw new LyraUserFacingError(this.localize("documentPreviewFailedToLoad"));const sanitized=parsed.html!==void 0&&DOMPurify?sanitizePassiveMarkup(DOMPurify,parsed.html,this.ownerDocument,"passive-document"):"",bodyHtml=sanitized.trim()?sanitized:null;if(!this.isCurrentLoad(generation,ownerView))return null;if(parsed.html&&!DOMPurify&&!parsed.text)throw new LyraUserFacingError(this.localize("documentViewerMissingSanitizer"));return{...parsed.from===void 0?{}:{fromAddress:parsed.from},toAddresses:parsed.to,email:{from:this.formatAddress(parsed.from),to:this.formatAddresses(parsed.to),subject:parsed.subject??"",date:parsed.date??"",bodyHtml,bodyText:bodyHtml?null:parsed.text??null,attachments:[...parsed.attachments]}}}formatAddress(value){if(!value)return"";if(value.group){const members=getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format(value.group.map(entry=>this.formatAddress(entry)).filter(Boolean));return value.name?this.localize("emailViewerGroupAddress",void 0,{name:value.name,members}):members}return value.name&&value.address?getListFormat(this.effectiveLocale,{style:"long",type:"unit"}).format([value.name,value.address]):value.address??value.name??""}formatAddresses(values){return getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format((values??[]).map(value=>this.formatAddress(value)).filter(Boolean))}formatDate(value){if(!value)return"";const date=new Date(value);return Number.isNaN(date.getTime())?value:getDateTimeFormat(this.effectiveLocale,{dateStyle:"medium",timeStyle:"short"}).format(date)}renderHeaders(email,fromAddress,toAddresses){return html`<div part="headers">
3
+ `)}}const QUOTE_SELECTOR='blockquote[type="cite" i], div.gmail_quote, div.yahoo_quoted, div[id^="divRplyFwdMsg"]';function parseHtmlDocument(html2,ownerDocument){const DOMParserCtor=ownerDocument.defaultView?.DOMParser;return DOMParserCtor?new DOMParserCtor().parseFromString(html2,"text/html"):null}function foldHtmlQuotes(html2,localize,expandedIndices,ownerDocument){const doc=parseHtmlDocument(html2,ownerDocument);if(!doc)return html2;for(const forged of doc.body.querySelectorAll("[data-quote-toggle], [data-quote-index], [data-email-chrome]"))forged.removeAttribute("data-quote-toggle"),forged.removeAttribute("data-quote-index"),forged.removeAttribute("data-email-chrome");const blocks=doc.body.querySelectorAll(QUOTE_SELECTOR),expandedQuotes=new Set(expandedIndices);return blocks.forEach((block,index)=>{const expanded=expandedQuotes.has(index);block.setAttribute("part","quoted"),expanded||block.setAttribute("hidden",""),block.setAttribute("data-quote-index",String(index));const button=doc.createElement("button");button.type="button",button.setAttribute("part","quote-toggle"),button.setAttribute("data-email-chrome","quote-toggle"),button.setAttribute("aria-expanded",String(expanded)),button.setAttribute("data-quote-toggle",String(index)),button.textContent=localize(expanded?"emailViewerHideQuoted":"emailViewerShowQuoted"),block.before(button)}),doc.body.innerHTML}function isQuoteToggleElement(target){const candidate=target;return candidate.nodeType===1&&candidate.localName==="button"&&candidate.hasAttribute("data-quote-toggle")}class LyraEmailViewer extends TextViewerTarget(LyraEmailViewerBase){constructor(){super(...arguments),this.src="",this.name="",this.maxHeight="",this.foldQuotes=!1,this.fetchState={kind:"idle"},this.textQuoteExpanded=!1,this.expandedHtmlQuoteIndices=[],this.generation=0,this.lastLoadSrc="",this.announcements=new ViewerAnnouncementController(this),this.foldedHtmlCache=null,this.detached=new DeferredTeardown(()=>{this.generation++,this.textQuoteExpanded=!1,this.expandedHtmlQuoteIndices=[],this.foldedHtmlCache=null}),this.onBodyClick=e=>{const target=e.composedPath().find(isQuoteToggleElement);if(!target)return;const index=target.getAttribute("data-quote-toggle"),block=this.renderRoot.querySelector(`[data-quote-index="${index}"]`),numericIndex=Number(index);if(!block||!Number.isInteger(numericIndex)||numericIndex<0)return;const restoreFocus=shadowFocusTarget(this)===target;this.expandedHtmlQuoteIndices=this.expandedHtmlQuoteIndices.includes(numericIndex)?this.expandedHtmlQuoteIndices.filter(value=>value!==numericIndex):[...this.expandedHtmlQuoteIndices,numericIndex],restoreFocus&&this.scheduleAfterUpdate(()=>{this.renderRoot.querySelector(`[data-quote-toggle="${numericIndex}"]`)?.focus()})}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeEmail:LYRA_DEFAULT_documentPreviewTypeEmail,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,documentViewerMissingSanitizer:LYRA_DEFAULT_documentViewerMissingSanitizer,download:LYRA_DEFAULT_download,emailViewerAttachments:LYRA_DEFAULT_emailViewerAttachments,emailViewerDate:LYRA_DEFAULT_emailViewerDate,emailViewerFrom:LYRA_DEFAULT_emailViewerFrom,emailViewerGroupAddress:LYRA_DEFAULT_emailViewerGroupAddress,emailViewerHideQuoted:LYRA_DEFAULT_emailViewerHideQuoted,emailViewerLabel:LYRA_DEFAULT_emailViewerLabel,emailViewerMissingParser:LYRA_DEFAULT_emailViewerMissingParser,emailViewerNoSubject:LYRA_DEFAULT_emailViewerNoSubject,emailViewerOpenAttachment:LYRA_DEFAULT_emailViewerOpenAttachment,emailViewerShowQuoted:LYRA_DEFAULT_emailViewerShowQuoted,emailViewerSubject:LYRA_DEFAULT_emailViewerSubject,emailViewerTo:LYRA_DEFAULT_emailViewerTo,emailViewerUnnamedAttachment:LYRA_DEFAULT_emailViewerUnnamedAttachment,fileSizeUnitB:LYRA_DEFAULT_fileSizeUnitB,fileSizeUnitGb:LYRA_DEFAULT_fileSizeUnitGb,fileSizeUnitKb:LYRA_DEFAULT_fileSizeUnitKb,fileSizeUnitMb:LYRA_DEFAULT_fileSizeUnitMb,fileSizeUnitTb:LYRA_DEFAULT_fileSizeUnitTb,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,open:LYRA_DEFAULT_open,popover:LYRA_DEFAULT_popover,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select}}static{this.styles=[LyraElement.styles,styles,viewerFrameStyles,srOnly,viewerLoadingStyles]}async search(query){if(this.foldQuotes&&this.fetchState.kind==="loaded"&&query.trim()&&query.length<=TEXT_QUOTE_LIMITS.maxQueryCodeUnits){const budget={remainingCodeUnits:TEXT_QUOTE_LIMITS.maxSearchWorkCodeUnits},matchesQuote=block=>createTextQuoteIndex(scopeFromElement(block),this.effectiveLocale).search(query,budget).length>0,{bodyHtml,bodyText}=this.fetchState.email;if(bodyHtml!==null){this.searchDocument?.html!==bodyHtml&&(this.searchDocument={html:bodyHtml,doc:parseHtmlDocument(bodyHtml,this.ownerDocument)});const next=new Set(this.expandedHtmlQuoteIndices);this.searchDocument.doc?.body.querySelectorAll(QUOTE_SELECTOR).forEach((block,index)=>{!next.has(index)&&matchesQuote(block)&&next.add(index)});const expanded=[...next];(expanded.length!==this.expandedHtmlQuoteIndices.length||expanded.some((value,index)=>value!==this.expandedHtmlQuoteIndices[index]))&&(this.expandedHtmlQuoteIndices=expanded,await this.updateComplete)}else if(bodyText!==null){const split=splitTrailingQuoteBlock(bodyText),quote=this.ownerDocument.createElement("pre");quote.textContent=split?.quoted??"",split&&!this.textQuoteExpanded&&matchesQuote(quote)&&(this.textQuoteExpanded=!0,await this.updateComplete)}}return super.search(query)}async searchNext(){return super.searchNext()}async searchPrevious(){return super.searchPrevious()}clearSearch(){super.clearSearch()}textContentRoot(){return this.renderRoot.querySelector('[part="body"]')}buildTextScope(root){return scopeFromElement(root,void 0,element=>this.foldQuotes&&element.localName==="button"&&element.getAttribute("data-email-chrome")==="quote-toggle")}connectedCallback(){super.connectedCallback(),this.announcements.connect(),!this.detached.cancel()&&this.hasUpdated&&this.src.trim()&&this.src===this.lastLoadSrc&&this.scheduleAfterUpdate(()=>{this.load()})}disconnectedCallback(){this.announcements.disconnect(),super.disconnectedCallback(),this.detached.schedule()}adoptedCallback(){super.adoptedCallback(),this.detached.flush(),this.announcements.adopted()}willUpdate(changed){super.willUpdate(changed),(changed.has("src")||changed.has("foldQuotes"))&&(this.textQuoteExpanded=!1,this.expandedHtmlQuoteIndices=[])}updated(changed){super.updated(changed),this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument")),changed.has("src")&&this.scheduleAfterUpdate(()=>{this.load()})}async load(){const generation=++this.generation,signal=this.beginAbortableLoad();if(this.lastLoadSrc=this.src,!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){this.failWithLocalizedMessage(this.localize("documentPreviewUrlNotAllowed"));return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isCurrentLoad(generation,fetchTarget.view))return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const buffer=await readResponseArrayBuffer(response);if(!this.isCurrentLoad(generation,fetchTarget.view))return;const result=await this.parse(buffer,generation,fetchTarget.view);result&&this.isCurrentLoad(generation,fetchTarget.view)&&(this.fetchState={kind:"loaded",...result})}catch(error){if(isAbortError(error)||!this.isCurrentLoad(generation,fetchTarget.view))return;this.fetchState={kind:"error",message:error instanceof LyraUserFacingError?error.message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")},this.emit("lr-render-error",{error})}}failWithLocalizedMessage(message){const error=new LyraUserFacingError(message);this.fetchState={kind:"error",message},this.emit("lr-render-error",{error})}isCurrentLoad(generation,ownerView){return this.isConnected&&generation===this.generation&&this.ownerDocument.defaultView===ownerView}async parse(buffer,generation,ownerView){const{PostalMime,DOMPurify}=await loadEmailDeps();if(!this.isCurrentLoad(generation,ownerView))return null;if(!PostalMime)throw new LyraUserFacingError(this.localize("emailViewerMissingParser"));const rawParsed=await PostalMime.parse(buffer);if(!this.isCurrentLoad(generation,ownerView))return null;const parsed=normalizeParsedEmail(rawParsed);if(!parsed)throw new LyraUserFacingError(this.localize("documentPreviewFailedToLoad"));const sanitized=parsed.html!==void 0&&DOMPurify?sanitizePassiveMarkup(DOMPurify,parsed.html,this.ownerDocument,"passive-document"):"",bodyHtml=sanitized.trim()?sanitized:null;if(!this.isCurrentLoad(generation,ownerView))return null;if(parsed.html&&!DOMPurify&&!parsed.text)throw new LyraUserFacingError(this.localize("documentViewerMissingSanitizer"));return{...parsed.from===void 0?{}:{fromAddress:parsed.from},toAddresses:parsed.to,email:{from:this.formatAddress(parsed.from),to:this.formatAddresses(parsed.to),subject:parsed.subject??"",date:parsed.date??"",bodyHtml,bodyText:bodyHtml?null:parsed.text??null,attachments:[...parsed.attachments]}}}formatAddress(value){if(!value)return"";if(value.group){const members=getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format(value.group.map(entry=>this.formatAddress(entry)).filter(Boolean));return value.name?this.localize("emailViewerGroupAddress",void 0,{name:value.name,members}):members}return value.name&&value.address?getListFormat(this.effectiveLocale,{style:"long",type:"unit"}).format([value.name,value.address]):value.address??value.name??""}formatAddresses(values){return getListFormat(this.effectiveLocale,{style:"long",type:"conjunction"}).format((values??[]).map(value=>this.formatAddress(value)).filter(Boolean))}formatDate(value){if(!value)return"";const date=new Date(value);return Number.isNaN(date.getTime())?value:getDateTimeFormat(this.effectiveLocale,{dateStyle:"medium",timeStyle:"short"}).format(date)}renderHeaders(email,fromAddress,toAddresses){return html`<div part="headers">
4
4
  <span part="from-label">${this.localize("emailViewerFrom")}</span><span part="from">${fromAddress?this.formatAddress(fromAddress):email.from}</span>
5
5
  <span part="to-label">${this.localize("emailViewerTo")}</span><span part="to">${toAddresses?this.formatAddresses(toAddresses):email.to}</span>
6
6
  <span part="subject-label">${this.localize("emailViewerSubject")}</span><span part="subject">${email.subject||this.localize("emailViewerNoSubject")}</span>
@@ -13,7 +13,7 @@ import{__decorate}from"tslib";import{html,nothing}from"lit";import{property,stat
13
13
  <span part="page-indicator">${this.localize("pdfViewerPageOf",void 0,{page:numberFormat.format(this.page),total:numberFormat.format(pageCount)})}</span>
14
14
  <button type="button" part="next-button" data-action="next" ?disabled=${this.page>=pageCount} @click=${this.nextPage}>${this.localize("pdfViewerNextPage")}</button>
15
15
  <button type="button" part="zoom-out-button" data-action="zoom-out" ?disabled=${this.zoom<=MIN_ZOOM} @click=${this.zoomOut}>${this.localize("pdfViewerZoomOut")}</button>
16
- <span part="zoom-indicator" aria-label=${this.localize("pdfViewerCurrentZoom",void 0,{percent:formattedZoom})}>${this.localize("pdfViewerCurrentZoom",void 0,{percent:formattedZoom})}</span>
16
+ <span part="zoom-indicator">${this.localize("pdfViewerCurrentZoom",void 0,{percent:formattedZoom})}</span>
17
17
  <button type="button" part="zoom-in-button" data-action="zoom-in" ?disabled=${this.zoom>=MAX_ZOOM} @click=${this.zoomIn}>${this.localize("pdfViewerZoomIn")}</button>
18
18
  </div>`}async renderPage(pageNumber,canvas){if(this.loadState.kind!=="ready")return;const version=++this.pageRenderGeneration;this.pageRenderVersions.set(pageNumber,version);const doc=this.loadState.doc,zoom=this.zoom;let renderTask;this.setPageError(canvas,!1),this.pageRenderTasks.get(pageNumber)?.cancel(),this.pageRenderTasks.delete(pageNumber),this.textLayers.get(pageNumber)?.cancel(),this.textLayers.delete(pageNumber);try{const page=await doc.getPage(pageNumber);if(this.loadState.kind!=="ready"||this.loadState.doc!==doc||this.pageRenderVersions.get(pageNumber)!==version||this.pageCanvases.get(pageNumber)!==canvas)return;const viewport=page.getViewport({scale:zoom}),allocation=boundedPdfCanvas(canvas,viewport);canvas.width=allocation.pixelWidth,canvas.height=allocation.pixelHeight,canvas.style.width=`${viewport.width}px`,canvas.style.height=`${viewport.height}px`;const container=this.textLayerContainers.get(pageNumber);container&&(container.style.width=`${viewport.width}px`,container.style.height=`${viewport.height}px`,container.style.setProperty("--total-scale-factor",String(zoom)));const highlightLayerEl=this.pageHighlightLayerElements.get(pageNumber);highlightLayerEl&&(highlightLayerEl.style.width=`${viewport.width}px`,highlightLayerEl.style.height=`${viewport.height}px`);const canvasContext=canvas.getContext("2d");if(!canvasContext)throw new Error("Canvas 2D context is unavailable.");if(canvasContext.setTransform(allocation.scaleX,0,0,allocation.scaleY,0,0),renderTask=page.render({canvasContext,viewport}),this.pageRenderTasks.set(pageNumber,renderTask),this.renderTextLayer(pageNumber,page,viewport,version).catch(error=>{!isAbortError(error)&&this.isConnected&&this.loadState.kind==="ready"&&this.loadState.doc===doc&&this.pageRenderVersions.get(pageNumber)===version&&this.pageCanvases.get(pageNumber)===canvas&&this.emit("lr-render-error",{error})}),await renderTask.promise,!this.isConnected||this.loadState.kind!=="ready"||this.loadState.doc!==doc||this.pageRenderVersions.get(pageNumber)!==version||this.pageCanvases.get(pageNumber)!==canvas)return;this.setPageError(canvas,!1)}catch(error){!isAbortError(error)&&this.isConnected&&this.loadState.kind==="ready"&&this.loadState.doc===doc&&this.pageRenderVersions.get(pageNumber)===version&&this.pageCanvases.get(pageNumber)===canvas&&(this.setPageError(canvas,!0),this.emit("lr-render-error",{error}))}finally{renderTask&&this.pageRenderTasks.get(pageNumber)===renderTask&&this.pageRenderTasks.delete(pageNumber)}}setPageError(canvas,failed){const fallback=canvas.parentElement?.querySelector('[part~="page-error"]');fallback&&(fallback.setAttribute("part",failed?"page-error page-error-visible":"page-error"),fallback.hidden=!failed,fallback.textContent=failed?this.localize("documentPreviewFailedToLoad"):"")}async renderTextLayer(pageNumber,page,viewport,version){const container=this.textLayerContainers.get(pageNumber);if(!container||!page.streamTextContent||this.loadState.kind!=="ready")return;const pdfjsLib=await this.loadLibrary(this.workerSrc||null);if(!pdfjsLib||!pdfjsLib.TextLayer||this.pageRenderVersions.get(pageNumber)!==version||this.textLayerContainers.get(pageNumber)!==container)return;this.mountedPageTextIndexes.delete(pageNumber),container.replaceChildren();const textLayer=new pdfjsLib.TextLayer({textContentSource:boundedPdfTextLayerSource(page.streamTextContent()),container,viewport});this.textLayers.set(pageNumber,textLayer);const renderPromise=textLayer.render().then(()=>{},error=>{!isAbortError(error)&&this.isConnected&&this.textLayers.get(pageNumber)===textLayer&&this.emit("lr-render-error",{error})});this.textLayerReadyPromises.set(pageNumber,renderPromise),await renderPromise,this.textLayers.get(pageNumber)===textLayer&&this.pageRenderVersions.get(pageNumber)===version&&(this.markTextRunParts(container),this.resolveMountedPageHighlights(),this.searchMatches.some(match=>match.page===pageNumber)&&this.paintSearchMatches(pageNumber))}markTextRunParts(container){const doc=container.ownerDocument,walker=doc.createTreeWalker(container,doc.defaultView?.NodeFilter.SHOW_ELEMENT??1);let visited=0,node;for(;visited++<TEXT_QUOTE_LIMITS.maxTraversalNodes&&(node=walker.nextNode());){const run=node;(run.localName==="span"||run.localName==="br")&&run.setAttribute("part","text-span")}}pageCanvasRef(pageNumber){let callback=this.pageCanvasRefs.get(pageNumber);return callback||(callback=element=>{if(!element){this.pageRenderVersions.delete(pageNumber),this.pageCanvases.delete(pageNumber),this.pageRenderTasks.get(pageNumber)?.cancel(),this.pageRenderTasks.delete(pageNumber),this.pageHighlightItems.delete(pageNumber),this.pageCanvasRefs.delete(pageNumber);return}this.pageCanvases.set(pageNumber,element),this.renderPage(pageNumber,element)},this.pageCanvasRefs.set(pageNumber,callback)),callback}textLayerContainerRef(pageNumber){let callback=this.textLayerContainerRefs.get(pageNumber);return callback||(callback=element=>{if(!element){this.textLayerContainers.delete(pageNumber),this.mountedPageTextIndexes.delete(pageNumber),this.textLayers.get(pageNumber)?.cancel(),this.textLayers.delete(pageNumber),this.textLayerReadyPromises.delete(pageNumber),this.pageHighlightItems.delete(pageNumber),this.textLayerContainerRefs.delete(pageNumber);return}this.textLayerContainers.set(pageNumber,element)},this.textLayerContainerRefs.set(pageNumber,callback)),callback}renderBody(){switch(this.loadState.kind){case"ready":return html`${this.renderToolbar()}<lr-virtual-list part="pages" exportparts="page:page, page-canvas:page-canvas, page-error:page-error, text-layer:text-layer, text-span:text-span, search-match:search-match, search-match-active:search-match-active" .source=${this.indexedPages(this.loadState.pageCount)} .renderItem=${this.renderPageItem} .activeItemId=${this.scrollDrivenPage?"":this.page} @lr-visible-range-change=${this.onVisibleRangeChanged} @lr-virtual-scroll=${this.stopInternalEvent}></lr-virtual-list>`;case"loading":return renderViewerLoading(this.localize("loadingDocument"));case"error":return html`<div part="error">${this.loadState.message}</div>`;default:return html`<p class="empty-note">${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}}render(){const maxHeight=sanitizeCssLength(this.maxHeight);return html`<div
19
19
  part="base"
@@ -1,4 +1,4 @@
1
- import{html,nothing}from"lit";import{ref}from"lit/directives/ref.js";import{nextId}from"./a11y.js";import{composedContains}from"./overlay-stack.js";import{getActiveNativeModal,registerNativeModalContext}from"./native-modal-context.js";class NativeModalCarrier{constructor(host,options){this.host=host,this.options=options,this.requested=!1,this.helperSlot=nextId("native-modal-content"),this.inheritedInert=!1,this.capture=element=>{this.element!==element&&(this.hide(),this.element=element)},this.cancel=event=>{event.preventDefault(),this.options.onCancel(event)},this.closed=()=>{!this.releaseContext||!this.host.isConnected||!this.element||this.element.open||(this.host.removeAttribute("data-native-modal-active"),this.options.onUnexpectedClose(this.element))}}get helperMount(){return this.helperMountElement??null}prepare(enabled=!0){if(this.element?.matches(":modal")&&enabled)return;const modal=enabled?getActiveNativeModal(this.host.ownerDocument):null;this.requested=modal!==null&&!composedContains(modal,this.host)}render(content,semantics={}){return this.requested?html`<dialog
1
+ import{html,nothing}from"lit";import{ref}from"lit/directives/ref.js";import{nextId}from"./a11y.js";import{OwnedTimeout}from"./owned-timer.js";import{authoredOverlayInert}from"./overlay-manager.js";import{composedContains}from"./overlay-stack.js";import{getActiveNativeModal,registerNativeModalContext}from"./native-modal-context.js";class NativeModalCarrier{constructor(host,options){this.host=host,this.options=options,this.requested=!1,this.helperSlot=nextId("native-modal-content"),this.inheritedInert=!1,this.tracksPredecessorReopening=!1,this.recoveryGeneration=0,this.scheduleRecovery=()=>{if(this.recoveryTask.pending)return;const generation=this.recoveryGeneration,document=this.host.ownerDocument;this.recoveryTask.schedule(0,()=>{generation!==this.recoveryGeneration||document!==this.predecessorDocument||!this.releaseContext||(this.stopCoverObservation(),this.show())})},this.capture=element=>{this.element!==element&&(this.hide(),this.element=element)},this.cancel=event=>{event.preventDefault(),this.options.onCancel(event)},this.closed=()=>{!this.releaseContext||!this.host.isConnected||!this.element||this.element.open||(this.host.removeAttribute("data-native-modal-active"),this.options.onUnexpectedClose(this.element))},this.recoveryTask=new OwnedTimeout(host)}get helperMount(){return this.helperMountElement??null}prepare(enabled=!0){if(this.element?.matches(":modal")&&enabled)return;const modal=enabled?getActiveNativeModal(this.host.ownerDocument):null;this.requested=modal!==null&&!composedContains(modal,this.host)}render(content,semantics={}){return this.requested?html`<dialog
2
2
  data-native-modal-carrier
3
3
  part=${semantics.part??nothing}
4
4
  role=${semantics.role??"dialog"}
@@ -9,4 +9,4 @@ import{html,nothing}from"lit";import{ref}from"lit/directives/ref.js";import{next
9
9
  ${ref(this.capture)}
10
10
  @cancel=${this.cancel}
11
11
  @close=${this.closed}
12
- >${content}</dialog>`:semantics.part?html`<div part=${semantics.part}>${content}</div>`:content}renderHelperSlot(){return this.requested?html`<slot name=${this.helperSlot}></slot>`:html``}show(){const carrier=this.element;if(!this.requested||!carrier||!this.host.isConnected)return this.host.removeAttribute("data-native-modal-active"),!1;if(carrier.matches(":modal"))return this.host.setAttribute("data-native-modal-active",""),!0;carrier.open&&carrier.close(),this.releaseContext?.(),this.helperMountElement?.remove(),this.helperMountElement=this.host.ownerDocument.createElement("span"),this.helperMountElement.slot=this.helperSlot,this.helperMountElement.style.display="contents",this.host.append(this.helperMountElement),this.releaseContext=registerNativeModalContext(carrier,this.host,this.helperMountElement);const inert=carrier.inert&&!this.inheritedInert;carrier.inert=!0;try{carrier.showModal(),this.host.setAttribute("data-native-modal-active","")}catch(error){throw this.host.removeAttribute("data-native-modal-active"),this.releaseContext?.(),this.releaseContext=void 0,this.helperMountElement.remove(),this.helperMountElement=void 0,error}finally{this.inheritedInert=!inert&&this.host.inert,carrier.inert=inert||this.host.inert}return!0}hide(){this.host.removeAttribute("data-native-modal-active"),this.releaseContext?.(),this.releaseContext=void 0,this.helperMountElement?.remove(),this.helperMountElement=void 0,this.inheritedInert&&this.element&&(this.element.inert=!1),this.inheritedInert=!1,this.element?.open&&this.element.close()}}export{NativeModalCarrier};
12
+ >${content}</dialog>`:semantics.part?html`<div part=${semantics.part}>${content}</div>`:content}renderHelperSlot(){return this.requested?html`<slot name=${this.helperSlot}></slot>`:html``}show(){const carrier=this.element;if(!this.requested||!carrier||!this.host.isConnected)return this.stopRecovery(),this.host.removeAttribute("data-native-modal-active"),!1;if(this.predecessorDocument&&this.predecessorDocument!==this.host.ownerDocument&&this.stopRecovery(),carrier.matches(":modal"))return this.stopCoverObservation(),this.host.setAttribute("data-native-modal-active",""),!0;if(this.predecessors&&this.releaseContext){this.processPredecessorRecords(this.predecessorObserver?.takeRecords()??[]);const active=getActiveNativeModal(this.host.ownerDocument);if(active&&active!==carrier&&(!this.tracksPredecessorReopening||!this.predecessors.has(active)))return this.host.removeAttribute("data-native-modal-active"),this.observeCover(active),!0}this.stopCoverObservation(),carrier.open&&carrier.close(),this.predecessors||this.observePredecessors(),this.releaseContext?.(),this.helperMountElement?.remove(),this.helperMountElement=this.host.ownerDocument.createElement("span"),this.helperMountElement.slot=this.helperSlot,this.helperMountElement.style.display="contents",this.host.append(this.helperMountElement),this.releaseContext=registerNativeModalContext(carrier,this.host,this.helperMountElement);const inert=carrier.inert&&!this.inheritedInert;carrier.inert=!0;try{carrier.showModal(),this.host.setAttribute("data-native-modal-active","")}catch(error){throw this.stopRecovery(),this.host.removeAttribute("data-native-modal-active"),this.releaseContext?.(),this.releaseContext=void 0,this.helperMountElement.remove(),this.helperMountElement=void 0,error}finally{const hostInert=authoredOverlayInert(this.host);this.inheritedInert=!inert&&hostInert,carrier.inert=inert||hostInert}return!0}hide(){this.stopRecovery(),this.host.removeAttribute("data-native-modal-active"),this.releaseContext?.(),this.releaseContext=void 0,this.helperMountElement?.remove(),this.helperMountElement=void 0,this.inheritedInert&&this.element&&(this.element.inert=!1),this.inheritedInert=!1,this.element?.open&&this.element.close()}observePredecessors(){const document=this.host.ownerDocument,predecessors=new Set,roots=[document];for(;roots.length>0;){const walker=document.createTreeWalker(roots.pop(),1);let node;for(;node=walker.nextNode();){const element=node;element.localName==="dialog"&&element.matches(":modal")&&predecessors.add(element),element.shadowRoot&&roots.push(element.shadowRoot)}}this.predecessorDocument=document,this.predecessors=new WeakSet(predecessors);const Observer=document.defaultView?.MutationObserver;if(this.tracksPredecessorReopening=!!Observer,!Observer||predecessors.size===0)return;const observer=new Observer(records=>{this.predecessorObserver===observer&&this.processPredecessorRecords(records)});this.predecessorObserver=observer;for(const predecessor of predecessors)observer.observe(predecessor,{attributes:!0,attributeFilter:["open"],attributeOldValue:!0})}processPredecessorRecords(records){for(const record of records)record.attributeName==="open"&&record.oldValue===null&&this.predecessors?.delete(record.target)}observeCover(modal){if(this.coveringModal===modal)return;this.stopCoverObservation(),this.coveringModal=modal,modal.addEventListener("close",this.scheduleRecovery);const Observer=this.host.ownerDocument.defaultView?.MutationObserver;if(!Observer)return;const observer=new Observer(()=>{this.coveringObserver===observer&&this.scheduleRecovery()});this.coveringObserver=observer,observer.observe(modal,{attributes:!0,attributeFilter:["open"]});let ancestor=modal.parentNode;for(;ancestor;)observer.observe(ancestor,{childList:!0}),ancestor=ancestor.parentNode??(ancestor.nodeType===11&&"host"in ancestor?ancestor.host:null)}stopCoverObservation(){this.recoveryTask.cancel(),this.coveringModal?.removeEventListener("close",this.scheduleRecovery),this.coveringModal=void 0,this.coveringObserver?.disconnect(),this.coveringObserver=void 0}stopRecovery(){this.recoveryGeneration+=1,this.stopCoverObservation(),this.predecessorObserver?.disconnect(),this.predecessorObserver=void 0,this.tracksPredecessorReopening=!1,this.predecessors=void 0,this.predecessorDocument=void 0}}export{NativeModalCarrier};
@@ -66,6 +66,8 @@ isTopmost():boolean;
66
66
  isActive():boolean;
67
67
  /** Runs the backdrop callback only when this overlay is topmost. */
68
68
  dismissBackdrop():boolean;}
69
+ /** The host's authored inert state, excluding this manager's temporary background lease. */
70
+ export declare function authoredOverlayInert(host:HTMLElement):boolean;
69
71
  /**
70
72
  * Adds an overlay to the document stack. Modal entries load inerting, rendered-state tracking, and
71
73
  * optional scroll locking; `modal: false` retains the historical API while using the lean adapter.
@@ -1 +1 @@
1
- import{getActiveNativeModal,isPageHelperRegion}from"./native-modal-context.js";import{activateNonmodalOverlay}from"./nonmodal-overlay-manager.js";import{RenderedStateController}from"./rendered-state.js";import{lockScroll}from"./scroll-lock.js";import{acquireOverlayRoutingSuspension,activateOverlayStack,observeOverlayStack}from"./overlay-stack.js";const EMPTY_STACK={entries:[]},modalStates=new WeakMap;function modalStateFor(doc){const existing=modalStates.get(doc);if(existing)return existing;const state={document:doc,snapshot:EMPTY_STACK,registrations:0,externalModalSuspensions:new Set,inerted:new Map,pendingInertWrites:new Map,observedRoots:new Set,allowedParents:new Set,inertUpdateQueued:!1,started:!1};return modalStates.set(doc,state),state}function scheduleInertUpdate(state){state.inertUpdateQueued||(state.inertUpdateQueued=!0,queueMicrotask(()=>{state.inertUpdateQueued=!1,applyTopmostInert(state)}))}function pruneExternalModalSuspensions(state){let changed=!1;for(const entry of state.externalModalSuspensions)entry.root.isConnected&&entry.root.ownerDocument===state.document||(entry.active=!1,state.externalModalSuspensions.delete(entry),entry.releaseRouting(),changed=!0);return changed}function movesStackHost(state,record){for(const entry of state.snapshot.entries)for(const list of[record.addedNodes,record.removedNodes])for(const node of list)if(node.contains(entry.host))return!0;return!1}function handleMutations(state,records){const prunedExternalModal=pruneExternalModalSuspensions(state);let needsInertUpdate=prunedExternalModal;for(let index=0;index<records.length;index++){const record=records[index];if(!record)continue;if(record.type==="childList"){(state.allowedParents.has(record.target)||movesStackHost(state,record))&&(needsInertUpdate=!0);continue}if(record.attributeName==="open"){needsInertUpdate=!0;continue}const element=record.target;let nextRecord;for(let nextIndex=index+1;nextIndex<records.length;nextIndex++){const candidate=records[nextIndex];if(candidate?.type==="attributes"&&candidate.attributeName==="inert"&&candidate.target===element){nextRecord=candidate;break}}const newValue=nextRecord?nextRecord.oldValue!==null:element.hasAttribute("inert"),pending=state.pendingInertWrites.get(element);if(pending?.[0]===newValue){pending.shift(),pending.length===0&&state.pendingInertWrites.delete(element);continue}state.inerted.has(element)&&(state.inerted.set(element,newValue),needsInertUpdate=!0)}needsInertUpdate&&(prunedExternalModal?applyTopmostInert(state):scheduleInertUpdate(state)),stopModalStateIfIdle(state)}const mutationObserverOptions={attributeFilter:["inert","open"],attributeOldValue:!0,attributes:!0,childList:!0,subtree:!0};function observeMutationRoot(state,root){!state.observer||state.observedRoots.has(root)||(state.observer.observe(root===state.document?state.document.documentElement:root,mutationObserverOptions),state.observedRoots.add(root))}function startModalState(state){if(state.started)return;state.started=!0;const Observer=state.document.defaultView?.MutationObserver??MutationObserver;state.observer=new Observer(records=>handleMutations(state,records)),observeMutationRoot(state,state.document),state.unsubscribeStack=observeOverlayStack(state.document,snapshot=>{state.snapshot=snapshot,applyTopmostInert(state)})}function stopModalState(state){if(state.started){state.started=!1,state.unsubscribeStack?.(),state.unsubscribeStack=void 0;for(const[element,intended]of state.inerted)element.inert=intended;state.inerted.clear(),state.observer?.disconnect(),state.observer=void 0,state.observedRoots.clear(),state.pendingInertWrites.clear(),state.snapshot=EMPTY_STACK}}function stopModalStateIfIdle(state){state.registrations===0&&state.externalModalSuspensions.size===0&&stopModalState(state)}function retainModalState(doc){const state=modalStateFor(doc);state.registrations++,startModalState(state);let active=!0;return()=>{active&&(active=!1,state.registrations--,stopModalStateIfIdle(state))}}function setInertByManager(state,element,value){if(element.inert!==value){if(state.observer&&state.observedRoots.has(element.getRootNode())){let pending=state.pendingInertWrites.get(element);pending||(pending=[],state.pendingInertWrites.set(element,pending)),pending.push(value)}else state.pendingInertWrites.delete(element);element.inert=value}}function inertElement(state,element,desired){if(!("inert"in element)||element.localName==="dialog"&&element.matches(":modal")||isPageHelperRegion(element))return;const htmlElement=element;desired.add(htmlElement),state.inerted.has(htmlElement)||state.inerted.set(htmlElement,htmlElement.inert),setInertByManager(state,htmlElement,!0)}function pathParent(element){return element.assignedSlot??element.parentNode}function parentPathElement(parent){return parent.nodeType===Node.ELEMENT_NODE?parent:parent.host??null}function composedChildren(parent){return parent.localName==="slot"?parent.assignedElements({flatten:!0}):"children"in parent?Array.from(parent.children):[]}function isShadowRoot(node){return node.nodeType===11&&"host"in node}function addAllowedPath(allowed,host,doc){let current=host;for(;current&&current!==doc.body&&current!==doc.documentElement;){const parent=pathParent(current);if(!parent)break;let children=allowed.get(parent);children||(children=new Set,allowed.set(parent,children)),children.add(current),current=parentPathElement(parent)}}function modalAllowedRoot(entry,doc){const explicit=entry.modalRoot?.()??null;return explicit?.isConnected&&explicit.ownerDocument===doc?explicit:entry.host}function applyTopmostInert(state){let modalIndex=-1;for(let index=state.snapshot.entries.length-1;index>=0;index--)if(state.snapshot.entries[index]?.modal){modalIndex=index;break}const desired=new Set;if(state.allowedParents=new Set,state.externalModalSuspensions.size>0){const allowed=new Map;for(const suspension of state.externalModalSuspensions)addAllowedPath(allowed,suspension.root,state.document);inertOutsideAllowedPaths(state,allowed,desired)}else if(modalIndex!==-1){const allowed=new Map;for(const entry of state.snapshot.entries.slice(modalIndex))if(entry.host.isConnected){addAllowedPath(allowed,modalAllowedRoot(entry,state.document),state.document);for(const root of entry.auxiliaryRoots?.()??[])root.isConnected&&root.ownerDocument===state.document&&addAllowedPath(allowed,root,state.document)}const nativeModal=getActiveNativeModal(state.document);nativeModal&&addAllowedPath(allowed,nativeModal,state.document),inertOutsideAllowedPaths(state,allowed,desired)}for(const[element,intended]of state.inerted)desired.has(element)||(setInertByManager(state,element,intended),state.inerted.delete(element))}function inertOutsideAllowedPaths(state,allowed,desired){for(const[parent,children]of allowed){state.allowedParents.add(parent),isShadowRoot(parent)&&observeMutationRoot(state,parent);for(const child of composedChildren(parent))children.has(child)||inertElement(state,child,desired)}}function activateOverlay(options){if(options.modal===!1&&options.trapFocus===!1&&!options.suspendWhenUnrendered&&!options.lockScroll)return activateNonmodalOverlay(options);const modal=options.modal!==!1;let releaseModalState,releaseScrollLock,renderedState;const coreHandle=activateOverlayStack({...options,initiallySuspended:options.suspendWhenUnrendered===!0,modal,trapFocus:options.trapFocus!==!1,onRegistered:doc=>{modal&&(releaseModalState=retainModalState(doc)),options.lockScroll&&(releaseScrollLock=lockScroll(doc))},onUnregistered:(_doc,deferResourceRelease)=>{const releaseModal=releaseModalState;releaseModalState=void 0;const release=releaseScrollLock;releaseScrollLock=void 0;const deferredRelease=release&&deferResourceRelease?release:void 0;return release&&!deferResourceRelease&&release(),releaseModal?.(),deferredRelease},onDeactivate:()=>renderedState?.stop()});return coreHandle.isActive()?(options.suspendWhenUnrendered&&(renderedState=new RenderedStateController(options.host,options.panel,rendered=>{if(!coreHandle.isActive())return;if(!rendered){coreHandle.suspend();return}const wasTopmost=coreHandle.isTopmost();coreHandle.resume(),!wasTopmost&&coreHandle.isTopmost()&&queueMicrotask(()=>coreHandle.focusInitial())}),renderedState.start()),{focusInitial:()=>{renderedState?.check(),coreHandle.focusInitial()},focusAutofocus:()=>(renderedState?.check(),coreHandle.focusAutofocus()),updateRestoreFocusTo:target=>coreHandle.updateRestoreFocusTo(target),deactivate:deactivateOptions=>coreHandle.deactivate(deactivateOptions),suspend:()=>coreHandle.suspend(),resume:()=>{renderedState&&!renderedState.check()||coreHandle.resume()},isTopmost:()=>(renderedState?.check(),coreHandle.isTopmost()),isActive:()=>coreHandle.isActive(),dismissBackdrop:()=>(renderedState?.check(),coreHandle.dismissBackdrop())}):coreHandle}function suspendLyraModalsFor(externalModal){if(!externalModal.isConnected)return()=>{};const state=modalStateFor(externalModal.ownerDocument);startModalState(state);const entry={root:externalModal,active:!0,releaseRouting:()=>{},state};return state.externalModalSuspensions.add(entry),entry.releaseRouting=acquireOverlayRoutingSuspension(state.document),applyTopmostInert(state),()=>{entry.active&&(entry.active=!1,entry.state.externalModalSuspensions.delete(entry),entry.releaseRouting(),applyTopmostInert(entry.state),stopModalStateIfIdle(entry.state))}}import{collectAutofocusElements,collectFocusableElements,composedContains,deepActiveElement}from"./overlay-stack.js";export{activateOverlay,collectAutofocusElements,collectFocusableElements,composedContains,deepActiveElement,suspendLyraModalsFor};
1
+ import{getActiveNativeModal,isPageHelperRegion}from"./native-modal-context.js";import{activateNonmodalOverlay}from"./nonmodal-overlay-manager.js";import{RenderedStateController}from"./rendered-state.js";import{lockScroll}from"./scroll-lock.js";import{acquireOverlayRoutingSuspension,activateOverlayStack,observeOverlayStack}from"./overlay-stack.js";const EMPTY_STACK={entries:[]},modalStates=new WeakMap;function authoredOverlayInert(host){const state=modalStates.get(host.ownerDocument);if(!state)return host.inert;const records=state.observer?.takeRecords();return records?.length&&handleMutations(state,records),state.inerted.get(host)??host.inert}function modalStateFor(doc){const existing=modalStates.get(doc);if(existing)return existing;const state={document:doc,snapshot:EMPTY_STACK,registrations:0,externalModalSuspensions:new Set,inerted:new Map,pendingInertWrites:new Map,observedRoots:new Set,allowedParents:new Set,inertUpdateQueued:!1,started:!1};return modalStates.set(doc,state),state}function scheduleInertUpdate(state){state.inertUpdateQueued||(state.inertUpdateQueued=!0,queueMicrotask(()=>{state.inertUpdateQueued=!1,applyTopmostInert(state)}))}function pruneExternalModalSuspensions(state){let changed=!1;for(const entry of state.externalModalSuspensions)entry.root.isConnected&&entry.root.ownerDocument===state.document||(entry.active=!1,state.externalModalSuspensions.delete(entry),entry.releaseRouting(),changed=!0);return changed}function movesStackHost(state,record){for(const entry of state.snapshot.entries)for(const list of[record.addedNodes,record.removedNodes])for(const node of list)if(node.contains(entry.host))return!0;return!1}function handleMutations(state,records){const prunedExternalModal=pruneExternalModalSuspensions(state);let needsInertUpdate=prunedExternalModal;for(let index=0;index<records.length;index++){const record=records[index];if(!record)continue;if(record.type==="childList"){(state.allowedParents.has(record.target)||movesStackHost(state,record))&&(needsInertUpdate=!0);continue}if(record.attributeName==="open"){needsInertUpdate=!0;continue}const element=record.target;let nextRecord;for(let nextIndex=index+1;nextIndex<records.length;nextIndex++){const candidate=records[nextIndex];if(candidate?.type==="attributes"&&candidate.attributeName==="inert"&&candidate.target===element){nextRecord=candidate;break}}const newValue=nextRecord?nextRecord.oldValue!==null:element.hasAttribute("inert"),pending=state.pendingInertWrites.get(element);if(pending?.[0]===newValue){pending.shift(),pending.length===0&&state.pendingInertWrites.delete(element);continue}state.inerted.has(element)&&(state.inerted.set(element,newValue),needsInertUpdate=!0)}needsInertUpdate&&(prunedExternalModal?applyTopmostInert(state):scheduleInertUpdate(state)),stopModalStateIfIdle(state)}const mutationObserverOptions={attributeFilter:["inert","open"],attributeOldValue:!0,attributes:!0,childList:!0,subtree:!0};function observeMutationRoot(state,root){!state.observer||state.observedRoots.has(root)||(state.observer.observe(root===state.document?state.document.documentElement:root,mutationObserverOptions),state.observedRoots.add(root))}function startModalState(state){if(state.started)return;state.started=!0;const Observer=state.document.defaultView?.MutationObserver??MutationObserver;state.observer=new Observer(records=>handleMutations(state,records)),observeMutationRoot(state,state.document),state.unsubscribeStack=observeOverlayStack(state.document,snapshot=>{state.snapshot=snapshot,applyTopmostInert(state)})}function stopModalState(state){if(state.started){state.started=!1,state.unsubscribeStack?.(),state.unsubscribeStack=void 0;for(const[element,intended]of state.inerted)element.inert=intended;state.inerted.clear(),state.observer?.disconnect(),state.observer=void 0,state.observedRoots.clear(),state.pendingInertWrites.clear(),state.snapshot=EMPTY_STACK}}function stopModalStateIfIdle(state){state.registrations===0&&state.externalModalSuspensions.size===0&&stopModalState(state)}function retainModalState(doc){const state=modalStateFor(doc);state.registrations++,startModalState(state);let active=!0;return()=>{active&&(active=!1,state.registrations--,stopModalStateIfIdle(state))}}function setInertByManager(state,element,value){if(element.inert!==value){if(state.observer&&state.observedRoots.has(element.getRootNode())){let pending=state.pendingInertWrites.get(element);pending||(pending=[],state.pendingInertWrites.set(element,pending)),pending.push(value)}else state.pendingInertWrites.delete(element);element.inert=value}}function inertElement(state,element,desired){if(!("inert"in element)||element.localName==="dialog"&&element.matches(":modal")||isPageHelperRegion(element))return;const htmlElement=element;desired.add(htmlElement),state.inerted.has(htmlElement)||state.inerted.set(htmlElement,htmlElement.inert),setInertByManager(state,htmlElement,!0)}function pathParent(element){return element.assignedSlot??element.parentNode}function parentPathElement(parent){return parent.nodeType===Node.ELEMENT_NODE?parent:parent.host??null}function composedChildren(parent){return parent.localName==="slot"?parent.assignedElements({flatten:!0}):"children"in parent?Array.from(parent.children):[]}function isShadowRoot(node){return node.nodeType===11&&"host"in node}function addAllowedPath(allowed,host,doc){let current=host;for(;current&&current!==doc.body&&current!==doc.documentElement;){const parent=pathParent(current);if(!parent)break;let children=allowed.get(parent);children||(children=new Set,allowed.set(parent,children)),children.add(current),current=parentPathElement(parent)}}function modalAllowedRoot(entry,doc){const explicit=entry.modalRoot?.()??null;return explicit?.isConnected&&explicit.ownerDocument===doc?explicit:entry.host}function applyTopmostInert(state){let modalIndex=-1;for(let index=state.snapshot.entries.length-1;index>=0;index--)if(state.snapshot.entries[index]?.modal){modalIndex=index;break}const desired=new Set;if(state.allowedParents=new Set,state.externalModalSuspensions.size>0){const allowed=new Map;for(const suspension of state.externalModalSuspensions)addAllowedPath(allowed,suspension.root,state.document);inertOutsideAllowedPaths(state,allowed,desired)}else if(modalIndex!==-1){const allowed=new Map;for(const entry of state.snapshot.entries.slice(modalIndex))if(entry.host.isConnected){addAllowedPath(allowed,modalAllowedRoot(entry,state.document),state.document);for(const root of entry.auxiliaryRoots?.()??[])root.isConnected&&root.ownerDocument===state.document&&addAllowedPath(allowed,root,state.document)}const nativeModal=getActiveNativeModal(state.document);nativeModal&&addAllowedPath(allowed,nativeModal,state.document),inertOutsideAllowedPaths(state,allowed,desired)}for(const[element,intended]of state.inerted)desired.has(element)||(setInertByManager(state,element,intended),state.inerted.delete(element))}function inertOutsideAllowedPaths(state,allowed,desired){for(const[parent,children]of allowed){state.allowedParents.add(parent),isShadowRoot(parent)&&observeMutationRoot(state,parent);for(const child of composedChildren(parent))children.has(child)||inertElement(state,child,desired)}}function activateOverlay(options){if(options.modal===!1&&options.trapFocus===!1&&!options.suspendWhenUnrendered&&!options.lockScroll)return activateNonmodalOverlay(options);const modal=options.modal!==!1;let releaseModalState,releaseScrollLock,renderedState;const coreHandle=activateOverlayStack({...options,initiallySuspended:options.suspendWhenUnrendered===!0,modal,trapFocus:options.trapFocus!==!1,onRegistered:doc=>{modal&&(releaseModalState=retainModalState(doc)),options.lockScroll&&(releaseScrollLock=lockScroll(doc))},onUnregistered:(_doc,deferResourceRelease)=>{const releaseModal=releaseModalState;releaseModalState=void 0;const release=releaseScrollLock;releaseScrollLock=void 0;const deferredRelease=release&&deferResourceRelease?release:void 0;return release&&!deferResourceRelease&&release(),releaseModal?.(),deferredRelease},onDeactivate:()=>renderedState?.stop()});return coreHandle.isActive()?(options.suspendWhenUnrendered&&(renderedState=new RenderedStateController(options.host,options.panel,rendered=>{if(!coreHandle.isActive())return;if(!rendered){coreHandle.suspend();return}const wasTopmost=coreHandle.isTopmost();coreHandle.resume(),!wasTopmost&&coreHandle.isTopmost()&&queueMicrotask(()=>coreHandle.focusInitial())}),renderedState.start()),{focusInitial:()=>{renderedState?.check(),coreHandle.focusInitial()},focusAutofocus:()=>(renderedState?.check(),coreHandle.focusAutofocus()),updateRestoreFocusTo:target=>coreHandle.updateRestoreFocusTo(target),deactivate:deactivateOptions=>coreHandle.deactivate(deactivateOptions),suspend:()=>coreHandle.suspend(),resume:()=>{renderedState&&!renderedState.check()||coreHandle.resume()},isTopmost:()=>(renderedState?.check(),coreHandle.isTopmost()),isActive:()=>coreHandle.isActive(),dismissBackdrop:()=>(renderedState?.check(),coreHandle.dismissBackdrop())}):coreHandle}function suspendLyraModalsFor(externalModal){if(!externalModal.isConnected)return()=>{};const state=modalStateFor(externalModal.ownerDocument);startModalState(state);const entry={root:externalModal,active:!0,releaseRouting:()=>{},state};return state.externalModalSuspensions.add(entry),entry.releaseRouting=acquireOverlayRoutingSuspension(state.document),applyTopmostInert(state),()=>{entry.active&&(entry.active=!1,entry.state.externalModalSuspensions.delete(entry),entry.releaseRouting(),applyTopmostInert(entry.state),stopModalStateIfIdle(entry.state))}}import{collectAutofocusElements,collectFocusableElements,composedContains,deepActiveElement}from"./overlay-stack.js";export{activateOverlay,authoredOverlayInert,collectAutofocusElements,collectFocusableElements,composedContains,deepActiveElement,suspendLyraModalsFor};
@@ -1 +1 @@
1
- const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui",LYRA_PACKAGE_VERSION="28.1.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
1
+ const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui",LYRA_PACKAGE_VERSION="28.1.1";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
@@ -57,6 +57,8 @@ visually-hidden span spelling the current value out in text, the panel shows it
57
57
  field, and the selected palette swatch is marked with `aria-checked` plus a check mark rather than
58
58
  a tint alone. The palette is one roving `radiogroup` with a single tab stop: the arrow keys (Left/Right
59
59
  swap under RTL), Home and End move to and select the next enabled swatch, like `lr-swatch-picker`.
60
+ When required, the trigger also includes the localized `fieldRequired` description; the editable
61
+ value field exposes `aria-required`.
60
62
 
61
63
  Validation is projected onto both editing owners with an explicit stateful `aria-invalid`. A
62
64
  required empty picker starts pristine, so the popup trigger and panel value input both expose
@@ -60,8 +60,9 @@ resolves successfully). A failed or unavailable write emits the compatibility `l
60
60
 
61
61
  `file-status` is the one-letter git-status badge (`A`/`M`/`D`/`R`/`U`/`C`/`!`) rendered inside
62
62
  `[part="file-path"]`, present only for a file that has a `status`. The letter alone is meaningless to
63
- a screen reader, so the element carries the localized expansion as its `aria-label` — "Modified",
64
- "Added", … — reusing `<lr-file-tree>`'s shared `gitStatusAdded`/`gitStatusModified`/
63
+ a screen reader, so visually hidden text supplies the localized expansion — "Modified", "Added",
64
+ … — in the file button's name, while the visual letter is hidden from assistive technology.
65
+ It reuses `<lr-file-tree>`'s shared `gitStatusAdded`/`gitStatusModified`/
65
66
  `gitStatusDeleted`/`gitStatusRenamed`/`gitStatusUntracked`/`gitStatusConflicted`/`gitStatusIgnored`
66
67
  message keys, so one `registerLyraLocale()` registration (or one `.strings` override) translates the
67
68
  badge in both components at once.
@@ -109,6 +109,8 @@ combobox with a permanently inert popup state — opening a one-row list to pick
109
109
  choice is pure friction with no real decision behind it. It never changes `value`/validity defaults
110
110
  on its own: an unselected single-option select stays unselected (and a `required` one stays invalid)
111
111
  exactly like the multi-option case, until the trigger is actually activated.
112
+ In this button mode, a required field is described with the localized `fieldRequired` message;
113
+ the normal combobox trigger continues to expose `aria-required`.
112
114
 
113
115
  **Properties:**
114
116
 
@@ -114,6 +114,10 @@ it with `[part="label"]`'s generated id whenever `label` is non-empty (so tabbin
114
114
  `exactValue`-focusable value still announces e.g. "Revenue $1.2K USD", including the visible unit,
115
115
  not just the bare value); each
116
116
  `[part="row-value"]` is paired the same way with its own row's `[part="row-label"]`.
117
+ Present metric and row labels expose the `term` role; their named values expose `definition`,
118
+ which supports these accessible names. A unit-only headline value also exposes `definition`
119
+ and includes the unit in its name. Values without a label or unit remain plain text; setting
120
+ `exactValue` still adds the existing focus stop and exact-value tooltip in an unlinked stat.
117
121
 
118
122
  **Themeable custom properties:** `--lr-stat-bg` (default `var(--lr-color-surface)`) is
119
123
  `[part="base"]`'s RESTING background — the tier a dashboard sits at all day, and the companion to
package/llms/peers.md CHANGED
@@ -38,7 +38,7 @@ for the page.
38
38
  | Peer | Range | Needed by |
39
39
  |---|---|---|
40
40
  | `@aceshooting/lyra-flags` | `^2.3.0` | _(loaded by a shared internal module)_ |
41
- | `@aceshooting/lyra-translations` | `^28.1.0` | _(not referenced by any component)_ |
41
+ | `@aceshooting/lyra-translations` | `^28.1.1` | _(not referenced by any component)_ |
42
42
  | `@aiden0z/pptx-renderer` | `^1.3.0` | `lr-pptx-viewer` |
43
43
  | `@sgratzl/chartjs-chart-boxplot` | `^4.0.0` | `lr-box-plot` |
44
44
  | `chart.js` | `^4.0.1` | `lr-bar-chart`, `lr-box-plot`, `lr-bubble-chart`, `lr-chart`, `lr-doughnut-chart`, `lr-histogram`, `lr-line-chart`, `lr-pie-chart`, `lr-polar-area-chart`, `lr-radar-chart`, `lr-scatter-chart` |