@evotecit/canopyx 0.3.18 → 0.3.21

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 (133) hide show
  1. package/CanopyX.Html/Assets/canopyx-board.css +12 -12
  2. package/CanopyX.Html/Assets/canopyx-board.js +1 -1
  3. package/CanopyX.Html/Assets/canopyx-calendar.css +70 -57
  4. package/CanopyX.Html/Assets/canopyx-calendar.js +14 -14
  5. package/CanopyX.Html/Assets/canopyx-cell-range.css +4 -4
  6. package/CanopyX.Html/Assets/canopyx-cell-range.js +1 -1
  7. package/CanopyX.Html/Assets/canopyx-changes.css +55 -55
  8. package/CanopyX.Html/Assets/canopyx-changes.js +1 -1
  9. package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -1
  10. package/CanopyX.Html/Assets/canopyx-column-groups.js +15 -9
  11. package/CanopyX.Html/Assets/canopyx-compare.css +4 -4
  12. package/CanopyX.Html/Assets/canopyx-compare.js +1 -1
  13. package/CanopyX.Html/Assets/canopyx-detail-rows.css +4 -4
  14. package/CanopyX.Html/Assets/canopyx-detail-rows.js +1 -1
  15. package/CanopyX.Html/Assets/canopyx-editing.css +3 -3
  16. package/CanopyX.Html/Assets/canopyx-editing.js +1 -1
  17. package/CanopyX.Html/Assets/canopyx-enhance.js +2 -2
  18. package/CanopyX.Html/Assets/canopyx-export.js +8 -8
  19. package/CanopyX.Html/Assets/canopyx-facets.css +19 -18
  20. package/CanopyX.Html/Assets/canopyx-facets.js +1 -1
  21. package/CanopyX.Html/Assets/canopyx-filter-editor.css +24 -24
  22. package/CanopyX.Html/Assets/canopyx-filter-editor.js +3 -3
  23. package/CanopyX.Html/Assets/canopyx-flow-checks.css +2 -2
  24. package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
  25. package/CanopyX.Html/Assets/canopyx-flow-command.css +3 -3
  26. package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
  27. package/CanopyX.Html/Assets/canopyx-flow-dialog.css +2 -2
  28. package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
  29. package/CanopyX.Html/Assets/canopyx-flow-drafts.css +2 -2
  30. package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
  31. package/CanopyX.Html/Assets/canopyx-flow-entry.css +24 -23
  32. package/CanopyX.Html/Assets/canopyx-flow-entry.js +4 -4
  33. package/CanopyX.Html/Assets/canopyx-flow-host.css +2 -2
  34. package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
  35. package/CanopyX.Html/Assets/canopyx-flow-module.mjs +4 -4
  36. package/CanopyX.Html/Assets/canopyx-flow-pick.css +4 -4
  37. package/CanopyX.Html/Assets/canopyx-flow-pick.js +1 -1
  38. package/CanopyX.Html/Assets/canopyx-flow-preview.css +1 -1
  39. package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
  40. package/CanopyX.Html/Assets/canopyx-flow-records.css +2 -2
  41. package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
  42. package/CanopyX.Html/Assets/canopyx-flow-tasks.css +4 -4
  43. package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
  44. package/CanopyX.Html/Assets/canopyx-flow.css +41 -41
  45. package/CanopyX.Html/Assets/canopyx-flow.js +1 -1
  46. package/CanopyX.Html/Assets/canopyx-format-editor.css +9 -9
  47. package/CanopyX.Html/Assets/canopyx-format-editor.js +1 -1
  48. package/CanopyX.Html/Assets/canopyx-formatting.css +13 -13
  49. package/CanopyX.Html/Assets/canopyx-formatting.js +3 -3
  50. package/CanopyX.Html/Assets/canopyx-forms.css +3 -3
  51. package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
  52. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +56 -46
  53. package/CanopyX.Html/Assets/canopyx-grid-options.css +8 -8
  54. package/CanopyX.Html/Assets/canopyx-grid-options.js +9 -2
  55. package/CanopyX.Html/Assets/canopyx-grid.css +99 -96
  56. package/CanopyX.Html/Assets/canopyx-grid.js +55 -45
  57. package/CanopyX.Html/Assets/canopyx-grouping.css +7 -7
  58. package/CanopyX.Html/Assets/canopyx-grouping.js +1 -1
  59. package/CanopyX.Html/Assets/canopyx-highlight.css +10 -10
  60. package/CanopyX.Html/Assets/canopyx-highlight.js +1 -1
  61. package/CanopyX.Html/Assets/canopyx-interactive.css +50 -49
  62. package/CanopyX.Html/Assets/canopyx-interactive.js +12 -11
  63. package/CanopyX.Html/Assets/canopyx-labels-de.js +4 -0
  64. package/CanopyX.Html/Assets/canopyx-labels-es.js +4 -0
  65. package/CanopyX.Html/Assets/canopyx-labels-fr.js +4 -0
  66. package/CanopyX.Html/Assets/canopyx-labels-it.js +4 -0
  67. package/CanopyX.Html/Assets/canopyx-labels-pl.js +4 -0
  68. package/CanopyX.Html/Assets/canopyx-layouts.css +9 -9
  69. package/CanopyX.Html/Assets/canopyx-layouts.js +2 -2
  70. package/CanopyX.Html/Assets/canopyx-link.css +3 -3
  71. package/CanopyX.Html/Assets/canopyx-link.js +3 -3
  72. package/CanopyX.Html/Assets/canopyx-links.js +2 -2
  73. package/CanopyX.Html/Assets/canopyx-live.css +2 -2
  74. package/CanopyX.Html/Assets/canopyx-live.js +1 -1
  75. package/CanopyX.Html/Assets/canopyx-matrix.css +31 -31
  76. package/CanopyX.Html/Assets/canopyx-matrix.js +1 -1
  77. package/CanopyX.Html/Assets/canopyx-module.mjs +13 -12
  78. package/CanopyX.Html/Assets/canopyx-pager.css +1 -1
  79. package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
  80. package/CanopyX.Html/Assets/canopyx-path.css +8 -8
  81. package/CanopyX.Html/Assets/canopyx-path.js +1 -1
  82. package/CanopyX.Html/Assets/canopyx-pivot.css +10 -10
  83. package/CanopyX.Html/Assets/canopyx-pivot.js +3 -3
  84. package/CanopyX.Html/Assets/canopyx-plan.css +24 -17
  85. package/CanopyX.Html/Assets/canopyx-plan.js +13 -9
  86. package/CanopyX.Html/Assets/canopyx-record-panel.css +47 -42
  87. package/CanopyX.Html/Assets/canopyx-record-panel.js +16 -9
  88. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +59 -56
  89. package/CanopyX.Html/Assets/canopyx-reporting.css +104 -101
  90. package/CanopyX.Html/Assets/canopyx-reporting.js +58 -55
  91. package/CanopyX.Html/Assets/canopyx-stack.css +6 -6
  92. package/CanopyX.Html/Assets/canopyx-stack.js +1 -1
  93. package/CanopyX.Html/Assets/canopyx-time-slider.css +5 -5
  94. package/CanopyX.Html/Assets/canopyx-time-slider.js +1 -1
  95. package/CanopyX.Html/Assets/canopyx-timeline.css +19 -19
  96. package/CanopyX.Html/Assets/canopyx-timeline.js +2 -2
  97. package/CanopyX.Html/Assets/canopyx-tree-tools.css +21 -21
  98. package/CanopyX.Html/Assets/canopyx-tree-tools.js +3 -3
  99. package/CanopyX.Html/Assets/canopyx-ui-accordion.css +119 -0
  100. package/CanopyX.Html/Assets/canopyx-ui-accordion.js +33 -0
  101. package/CanopyX.Html/Assets/canopyx-ui-menu.css +7 -7
  102. package/CanopyX.Html/Assets/canopyx-ui-menu.js +1 -1
  103. package/CanopyX.Html/Assets/canopyx-ui-module.mjs +39 -0
  104. package/CanopyX.Html/Assets/canopyx-ui-navigation.css +9 -9
  105. package/CanopyX.Html/Assets/canopyx-ui-navigation.js +5 -5
  106. package/CanopyX.Html/Assets/canopyx-ui-overlays.css +5 -5
  107. package/CanopyX.Html/Assets/canopyx-ui-overlays.js +5 -2
  108. package/CanopyX.Html/Assets/canopyx-ui-picker.css +2 -2
  109. package/CanopyX.Html/Assets/canopyx-ui-picker.js +1 -1
  110. package/CanopyX.Html/Assets/canopyx-ui-stepper.css +12 -12
  111. package/CanopyX.Html/Assets/canopyx-ui-stepper.js +1 -1
  112. package/CanopyX.Html/Assets/canopyx-ui-tabs.css +9 -8
  113. package/CanopyX.Html/Assets/canopyx-ui-tabs.js +7 -4
  114. package/CanopyX.Html/Assets/canopyx-ui.css +119 -0
  115. package/CanopyX.Html/Assets/canopyx-ui.js +37 -0
  116. package/CanopyX.Html/Assets/canopyx-view-intents.css +1 -1
  117. package/CanopyX.Html/Assets/canopyx-view-intents.js +1 -1
  118. package/CanopyX.Html/Assets/canopyx.css +47 -46
  119. package/CanopyX.Html/Assets/canopyx.js +12 -11
  120. package/JavaScript/column-groups.d.ts +24 -4
  121. package/JavaScript/grid.d.ts +11 -1
  122. package/JavaScript/hosts.d.ts +2 -0
  123. package/JavaScript/locales/de.mjs +4 -0
  124. package/JavaScript/locales/es.mjs +4 -0
  125. package/JavaScript/locales/fr.mjs +4 -0
  126. package/JavaScript/locales/it.mjs +4 -0
  127. package/JavaScript/locales/pl.mjs +4 -0
  128. package/JavaScript/protocol.d.ts +3 -0
  129. package/JavaScript/records.d.ts +2 -0
  130. package/JavaScript/ui.d.ts +70 -2
  131. package/README.md +76 -206
  132. package/README.nuget.md +63 -87
  133. package/package.json +14 -1
@@ -1,4 +1,4 @@
1
- (function(global){"use strict";const installed=new WeakSet();const part={version:"640ca4be173c3310",requires:["timeline"],install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,h,setText,fill,cellValue,cellText,gridFreeze}=context;DataGrid.prototype.validatePlanDefinition=function(decoded){const input=this.view.plan,calendar=this.view.calendar,columns=new Map(this.columns.map(column=>[column.id,column]));const kind=(id,type)=>typeof id==="string"&&columns.get(id)?.kind===type;if(!input||typeof input!=="object"||Array.isArray(input)||!calendar?.resources||!calendar.end||!calendar.resource||
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"db07c2eb53541d49",requires:["timeline"],install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,h,setText,fill,cellValue,cellText,gridFreeze}=context;DataGrid.prototype.validatePlanDefinition=function(decoded){const input=this.view.plan,calendar=this.view.calendar,columns=new Map(this.columns.map(column=>[column.id,column]));const kind=(id,type)=>typeof id==="string"&&columns.get(id)?.kind===type;if(!input||typeof input!=="object"||Array.isArray(input)||!calendar?.resources||!calendar.end||!calendar.resource||
2
2
  calendar.recurrence||calendar.sources?.length||calendar.create||calendar.drop||calendar.views?.length&&!calendar.views.includes("timeline")||
3
3
  ["criticalPath","proposeMoves","avoidOverlap"].some(key=>input[key]!==undefined&&typeof input[key]!=="boolean")||
4
4
  (input.baselineStart===undefined)!==(input.baselineEnd===undefined)||input.baselineStart!==undefined&&
@@ -21,28 +21,32 @@ add("dependency",edge.to.task,this.planText("planDependencyConflict",{task:edge.
21
21
  this.calKit.calOverlaps(proposal.start,proposal.end,start,end);if(this.view.plan.avoidOverlap!==false)for(const other of network.nodes.values()){const item=other.task;if(item.key!==task.key&&item.resource===proposal.resource&&overlap(item.start,item.end))
22
22
  add("overlap",item,this.planText("planOverlapConflict",{task:item.title}))}
23
23
  for(const range of this.calRanges)if(range.kind==="unavailable"&&(range.resource==null||range.resource===proposal.resource)&&overlap(range.start,range.end))
24
- add("unavailable",null,this.calLabels.calendarUnavailable);return problems}});const PLAN_METRICS=Object.freeze({actualMinHeight:20,actualBaselineGap:16,baselineMinWidth:3,baselineBottom:7});function planTaskTemplate(element,event,node,labels,milestone,critical,proposeMoves){element.classList.add("cx-plan-task");element.classList.toggle("cx-plan-milestone",milestone);element.classList.toggle("cx-plan-critical",!!critical);element.classList.toggle("cx-plan-conflict",!!node&&[...node.before,...node.after].some(edge=>edge.conflict));if(milestone)labels.push(this.planText("planMilestone"));if(critical)labels.push(this.planText("planCritical"));for(const edge of node?.before||[])if(edge.conflict)labels.push(this.planText("planDependencyConflict",{task:edge.from.task.title}));if(proposeMoves){element.setAttribute("aria-keyshortcuts","Alt+ArrowLeft Alt+ArrowRight Alt+ArrowUp Alt+ArrowDown");labels.push(this.planText("planMoveHint"))}
24
+ add("unavailable",null,this.calLabels.calendarUnavailable);return problems}});const PLAN_METRICS=Object.freeze({actualMinHeight:20,actualBaselineGap:16,baselineMinWidth:3,baselineBottom:7,dependencyLead:10});function planTaskTemplate(element,event,node,labels,milestone,critical,proposeMoves){element.classList.add("cx-plan-task");element.classList.toggle("cx-plan-milestone",milestone);element.classList.toggle("cx-plan-critical",!!critical);element.classList.toggle("cx-plan-conflict",!!node&&[...node.before,...node.after].some(edge=>edge.conflict));if(milestone)labels.push(this.planText("planMilestone"));if(critical)labels.push(this.planText("planCritical"));for(const edge of node?.before||[])if(edge.conflict)labels.push(this.planText("planDependencyConflict",{task:edge.from.task.title}));if(proposeMoves){element.setAttribute("aria-keyshortcuts","Alt+ArrowLeft Alt+ArrowRight Alt+ArrowUp Alt+ArrowDown");labels.push(this.planText("planMoveHint"))}
25
25
  element.setAttribute("aria-label",labels.join(", "));element.title=labels.join(", ")}
26
26
  function planLegendTemplate(){const legend=h("div","cx-plan-legend");for(const[kind,label]of[["critical","planCritical"],["baseline","planBaselineLabel"],["dependency","planDependencies"]]){const item=h("span"),mark=h("i","cx-plan-key-"+kind);mark.setAttribute("aria-hidden","true");item.append(mark,document.createTextNode(this.planText(label)));legend.appendChild(item)}
27
27
  const conflict=h("span"),mark=h("i","cx-plan-key-conflict");mark.setAttribute("aria-hidden","true");conflict.append(mark,document.createTextNode(this.planText("planConflict")));legend.appendChild(conflict);return legend}
28
28
  function planBaselineTemplate(element,lane,axis,from,to,text){const line=h("div","cx-plan-baseline");line.style.insetInlineStart=axis.x(from)+ "px";line.style.width=Math.max(PLAN_METRICS.baselineMinWidth,axis.x(to)- axis.x(from))+ "px";line.style.top=(Number.parseFloat(element.style.top)+ element._planHeight-PLAN_METRICS.baselineBottom)+ "px";line.title=text;line.setAttribute("aria-hidden","true");lane.appendChild(line)}
29
29
  function planLinksTemplate(axis,height){const svg=document.createElementNS("http://www.w3.org/2000/svg","svg");svg.classList.add("cx-plan-links");svg.setAttribute("aria-hidden","true");svg.style.width=axis.total+"px";svg.style.height=height;return svg}
30
- function planLinkTemplate(svg,axis,from,to,edge,critical,text){const mirror=x=>this.calRtl?axis.total-x:x,x1=mirror(from.end),x2=mirror(to.start),sign=this.calRtl?-1:1;const exit=x1-5*sign,entry=x2-10*sign;const edgeY=to.y>=from.y?from.bottom:from.top,corridor=edgeY +(to.y>=from.y?4:-4);const path=document.createElementNS(svg.namespaceURI,"path");const flat=Math.abs(from.y-to.y)<1&&(x2-x1)*sign>=-1;const route=flat?"M"+(Math.abs(x1-x2)<1?x1-5*sign:x1)+","+from.y+" H"+x2:"M"+exit+","+edgeY+" V"+corridor+" H"+entry+" V"+to.y+" H"+x2;const lead=x2-5*sign;const arrow=" M"+lead+","+(to.y-4)+" L"+x2+","+to.y+" L"+lead+","+(to.y+4);path.setAttribute("d",route+arrow);path.classList.toggle("cx-plan-link-conflict",edge.conflict);path.classList.toggle("cx-plan-link-critical",critical);const title=document.createElementNS(svg.namespaceURI,"title");title.textContent=text;path.appendChild(title);svg.appendChild(path)}
30
+ function planLinkTemplate(svg,axis,from,to,edge,critical,text){const mirror=x=>this.calRtl?axis.total-x:x,x1=mirror(from.end),x2=mirror(to.start),sign=this.calRtl?-1:1;const exit=x1-5*sign,entry=x2-PLAN_METRICS.dependencyLead*sign;const edgeY=to.y>=from.y?from.bottom:from.top,corridor=edgeY +(to.y>=from.y?4:-4);const path=document.createElementNS(svg.namespaceURI,"path");const flat=Math.abs(from.y-to.y)<1&&(x2-x1)*sign>=-1;const crossesLabel=flat&&[from.label,to.label].some(label=>label&&from.y>=label.top-1&&from.y<=label.bottom+1&&Math.max(x1,x2)>label.left&&Math.min(x1,x2)<label.right);const below=Math.max(from.bottom,to.bottom)- 1;const route=crossesLabel?"M"+x1+","+from.y+" V"+below+" H"+entry+" V"+to.y+" H"+x2:flat?"M"+(Math.abs(x1-x2)<1?x1-5*sign:x1)+","+from.y+" H"+x2:"M"+exit+","+edgeY+" V"+corridor+" H"+entry+" V"+to.y+" H"+x2;const lead=x2-5*sign;const arrow=" M"+lead+","+(to.y-4)+" L"+x2+","+to.y+" L"+lead+","+(to.y+4);path.setAttribute("d",route+arrow);path.classList.toggle("cx-plan-link-conflict",edge.conflict);path.classList.toggle("cx-plan-link-critical",critical);const title=document.createElementNS(svg.namespaceURI,"title");title.textContent=text;path.appendChild(title);svg.appendChild(path)}
31
31
  function planAgendaTemplate(labels){const root=h("div","cx-plan-agenda"),scroll=h("div","cx-plan-agenda-scroll"),list=h("div","cx-plan-agenda-list");const pager=h("nav","cx-plan-agenda-pager"),previous=h("button","cx-btn cx-plan-agenda-previous"),next=h("button","cx-btn cx-plan-agenda-next"),position=h("span","cx-plan-agenda-position");previous.type=next.type="button";previous.setAttribute("aria-label",labels.gridPreviousPage);next.setAttribute("aria-label",labels.gridNextPage);setText(previous,"\u2039");setText(next,"\u203a");pager.setAttribute("aria-label",labels.gridPaging);pager.append(previous,position,next);scroll.appendChild(list);root.append(scroll,pager);return{root,scroll,list,pager,previous,next,position,page:0}}
32
32
  function planAgendaPageTemplate(items,moves){const fragment=document.createDocumentFragment();let current=null,list=null;const heading=group=>{const section=h("section"),title=h("h3"),count=h("span","cx-plan-agenda-count");if(group.expandable){const button=h("button","cx-btn cx-plan-resource-toggle"),mark=h("span");button.type="button";mark.setAttribute("aria-hidden","true");setText(mark,group.row._open?"\u25be":"\u25b8");button.append(mark,document.createTextNode(group.label));button.dataset.cxPlanToggle=group.id;button.setAttribute("aria-expanded",String(!!group.row._open));title.appendChild(button)}else setText(title,group.label);setText(count,String(group.items.length));title.appendChild(count);list=h("ul");list.setAttribute("aria-label",group.label);section.append(title,list);fragment.appendChild(section);current=group};for(const item of items){if(item.kind==="resource"){heading(item.group);continue}
33
33
  if(current!==item.group)heading(item.group);const row=h("li"),button=h("button","cx-btn cx-cal-ev cx-plan-agenda-title"),dates=h("p"),meta=h("p","cx-plan-agenda-meta");button.type="button";setText(button,item.task.title);button.title=item.task.title;button.dataset.cxPlanRecord=item.task.key;button.dataset.cxPlanResource=item.group.id;button.dataset.cxEvent=item.task.id;button.dataset.cxRecord=item.task.key;button._calEvent={...item.task,resource:item.group.id};button.setAttribute("aria-label",[item.task.title,item.fullDates,item.meta].join(", "));if(moves)button.setAttribute("aria-keyshortcuts","Alt+ArrowLeft Alt+ArrowRight Alt+ArrowUp Alt+ArrowDown");setText(dates,item.dates);setText(meta,item.meta);row.classList.toggle("cx-plan-agenda-critical",item.critical);row.append(button,dates,meta);list.appendChild(row)}
34
34
  return fragment}
35
- const PLAN_LABELS={planMilestone:"Milestone",planCritical:"Critical path",planBaseline:"Baseline: {start} – {end}",planDependency:"{from} finishes before {to} starts",planDependencyConflict:"Dependency conflict with {task}",planOverlapConflict:"Overlaps {task}",planIncomplete:"The complete task network is unavailable; the host must check this proposal.",planInvalidRange:"The task must finish at or after its start.",planInvalidResource:"Choose a task resource.",planProposal:"Proposed {task}: {start} – {end}",planMoveHint:"Alt+Left or Alt+Right proposes a new date; Alt+Up or Alt+Down proposes a resource.",planConflict:"Conflict",planActual:"Actual",planPending:"Proposal awaiting the host",planBaselineLabel:"Baseline",planDependencies:"Dependencies"};const PLAN_EVENT=DataGrid.prototype.calEventElement;DataGrid.prototype.calEventElement=function(event,kind){const element=PLAN_EVENT.call(this,event,kind);if(this.view.plan&&kind==="lane"){this.planDecorate(element,event);this.planStart()}
35
+ const PLAN_LABELS={planMilestone:"Milestone",planCritical:"Critical path",planBaseline:"Baseline: {start} – {end}",planDependency:"{from} finishes before {to} starts",planDependencyConflict:"Dependency conflict with {task}",planOverlapConflict:"Overlaps {task}",planIncomplete:"The complete task network is unavailable; the host must check this proposal.",planInvalidRange:"The task must finish at or after its start.",planInvalidResource:"Choose a task resource.",planProposal:"Proposed {task}: {start} – {end}",planMoveHint:"Alt+Left or Alt+Right proposes a new date; Alt+Up or Alt+Down proposes a resource.",planConflict:"Conflict",planActual:"Actual",planPending:"Proposal awaiting the host",planBaselineLabel:"Baseline",planDependencies:"Dependencies"};const PLAN_EVENT=DataGrid.prototype.calEventElement;DataGrid.prototype.calEventElement=function(event,kind,day){const element=PLAN_EVENT.call(this,event,kind,day);if(this.view.plan&&kind==="lane"){this.planDecorate(element,event);this.planStart()}
36
36
  return element};const PLAN_LANES=DataGrid.prototype.tlPaintLanes;DataGrid.prototype.tlPaintLanes=function(...args){const result=PLAN_LANES.apply(this,args);if(this.view.plan&&this.tlCanvas&&this.calView==="timeline")this.planPaint();return result};Object.assign(DataGrid.prototype,{planDecorate(element,event){const network=this.planAnalyze(),node=network.nodes.get(event.key),labels=[this.calEventName(event)];const milestone=planMilestone(this,event),critical=this.view.plan.criticalPath!==false&&network.complete&&node?.critical;planTaskTemplate.call(this,element,event,node,labels,milestone,critical,this.view.plan.proposeMoves)},planPaint(){this.tlRoot.classList.add("cx-plan");this.host.classList.add("cx-plan-host");this.calRoot.classList.add("cx-plan-calendar");if(!this.planLegend){const legend=this.planLegend=planLegendTemplate.call(this);this.calBody.before(legend);this.lifetime.signal.addEventListener("abort",()=>{legend.remove();this.host.classList.remove("cx-plan-host");if(this.planFit&&this.host.style.maxHeight===this.planFit.written)this.host.style.maxHeight=this.planFit.inline;this.planAgendaModel=this.planAgendaState=null},{once:true})}
37
- const network=this.planAnalyze(),axis=this.tlAxis,positions=new Map(),canvasBox=this.tlCanvas.getBoundingClientRect();for(const lane of this.tlLanes.values()){for(const previous of lane.querySelectorAll(".cx-plan-baseline"))previous.remove();for(const element of lane.querySelectorAll(".cx-plan-task")){const task=element._calEvent;if(planMilestone(this,task))element.style.width="0px";const spec=this.view.plan;if(spec.baselineStart){element._planHeight??=Number.parseFloat(element.style.height);if(!planMilestone(this,task))element.style.height=Math.max(PLAN_METRICS.actualMinHeight,element._planHeight-PLAN_METRICS.actualBaselineGap)+ "px"}
38
- const rect=element.getBoundingClientRect(),start=axis.x(task.tlStart),end=axis.x(planMilestone(this,task)?task.tlStart:task.tlEnd);if(!positions.has(task.key))positions.set(task.key,{start,end,y:rect.top-canvasBox.top+rect.height / 2, top: rect.top - canvasBox.top, bottom: rect.bottom - canvasBox.top });
39
- const title=element.querySelector(".cx-cal-ev-title");if(title){title.title=task.title;element.classList.remove("cx-plan-label-before");const outside=title.scrollWidth>element.clientWidth-12||planMilestone(this,task);element.classList.toggle("cx-plan-label-outside",outside);const box=title.getBoundingClientRect(),x=axis.x(Date.now()),today=canvasBox.left+(this.calRtl?axis.total-x:x);element.classList.toggle("cx-plan-label-before",outside&&this.cal.now&&today>=box.left-4&&today<=box.right+4)}
37
+ const network=this.planAnalyze(),axis=this.tlAxis,positions=new Map(),canvasBox=this.tlCanvas.getBoundingClientRect();for(const lane of this.tlLanes.values()){for(const previous of lane.querySelectorAll(".cx-plan-baseline"))previous.remove();for(const element of lane.querySelectorAll(".cx-plan-task")){const task=element._calEvent;if(planMilestone(this,task))element.style.width="0px";const spec=this.view.plan;if(spec.baselineStart){element._planHeight??=Number.parseFloat(element.style.height);element.style.height=Math.max(PLAN_METRICS.actualMinHeight,element._planHeight-PLAN_METRICS.actualBaselineGap)+ "px"}
38
+ const rect=element.getBoundingClientRect(),start=axis.x(task.tlStart),end=axis.x(planMilestone(this,task)?task.tlStart:task.tlEnd);if(!positions.has(task.key))positions.set(task.key,{start,end,y:rect.top-canvasBox.top+rect.height / 2, top: rect.top - canvasBox.top, bottom: rect.bottom - canvasBox.top, element });
39
+ const title=element.querySelector(".cx-cal-ev-title");if(title){title.style.maxInlineSize="";title.title=task.title;element.classList.remove("cx-plan-label-before");const outside=title.scrollWidth>element.clientWidth-12||planMilestone(this,task);element.classList.toggle("cx-plan-label-outside",outside);const box=title.getBoundingClientRect(),x=axis.x(Date.now()),today=canvasBox.left+(this.calRtl?axis.total-x:x);element.classList.toggle("cx-plan-label-before",outside&&this.cal.now&&today>=box.left-4&&today<=box.right+4)}
40
40
  if(!spec.baselineStart||!spec.baselineEnd)continue;const from=planInstant(task.row.cells[spec.baselineStart]),to=planInstant(task.row.cells[spec.baselineEnd]);if(!Number.isFinite(from)||!Number.isFinite(to)||to<=from||from>=axis.to||to<axis.from)continue;const text=this.planText("planBaseline",{start:this.calFmt.longDay(this.calZone.day(from)),end:this.calFmt.longDay(this.calZone.day(to))});planBaselineTemplate(element,lane,axis,from,to,text);element._planName||=element.getAttribute("aria-label");element.setAttribute("aria-label",element._planName+"; "+text)}}
41
41
  for(const lane of this.tlLanes.values()){const rows=new Map();for(const element of lane.querySelectorAll(".cx-plan-task")){const key=element.style.top;if(!rows.has(key))rows.set(key,[]);rows.get(key).push({element,title:element.querySelector(".cx-cal-ev-title"),box:element.getBoundingClientRect()})}
42
42
  const overlaps=(a,b)=>a.left<b.right&&a.right>b.left&&a.top<b.bottom&&a.bottom>b.top;for(const items of rows.values()){items.sort((a,b)=>a.box.left-b.box.left);for(const[index,item]of items.entries()){if(!item.title||!item.element.classList.contains("cx-plan-label-outside")||item.element.classList.contains("cx-plan-milestone"))continue;const box=item.title.getBoundingClientRect();if([items[index-1],items[index+1]].some(other=>other&&(overlaps(box,other.box)||other.title&&overlaps(box,other.title.getBoundingClientRect()))))
43
- item.element.classList.remove("cx-plan-label-outside","cx-plan-label-before")}}}
43
+ item.element.classList.remove("cx-plan-label-outside","cx-plan-label-before")}}
44
+ const tasks=[...lane.querySelectorAll(".cx-plan-task")];for(const element of tasks.filter(task=>task.classList.contains("cx-plan-milestone"))){const title=element.querySelector(".cx-cal-ev-title");if(!title)continue;const box=element.getBoundingClientRect(),label=title.getBoundingClientRect();const obstacles=tasks.filter(task=>task!==element).flatMap(task=>[task,task.querySelector(".cx-cal-ev-title")]).filter(Boolean)
45
+ .map(task=>task.getBoundingClientRect()).filter(other=>other.top<label.bottom&&other.bottom>label.top);const rtl=this.calRtl,currentBefore=element.classList.contains("cx-plan-label-before");const gap=Math.max(0,currentBefore!==rtl?box.left-label.right:label.left-box.right);const successors=network.nodes.get(element._calEvent.key)?.after||[];const needsClearance=side=>successors.some(edge=>{const target=positions.get(edge.to.task.key);if(!target)return false;const x=canvasBox.left +(this.calRtl?axis.total-target.start:target.start);return side==="after"?x>box.right:x<box.left});const after=Math.max(0,Math.min(canvasBox.right,...obstacles.filter(other=>other.right>box.right+gap).map(other=>other.left))- box.right-gap -(needsClearance("after")?PLAN_METRICS.dependencyLead+2:0));const before=Math.max(0,box.left-gap-Math.max(canvasBox.left,...obstacles.filter(other=>other.left<box.left-gap).map(other=>other.right))-(needsClearance("before")?PLAN_METRICS.dependencyLead+2:0));const currentRoom=currentBefore!==rtl?before:after;const alternateRoom=currentBefore!==rtl?after:before;const flip=currentRoom<label.width&&alternateRoom>currentRoom;if(flip)element.classList.toggle("cx-plan-label-before");title.style.maxInlineSize=Math.min(parseFloat(getComputedStyle(title).maxInlineSize)||160,flip?alternateRoom:currentRoom)+ "px"}}
46
+ for(const position of positions.values()){const title=position.element.querySelector(".cx-cal-ev-title"),rect=title?.getBoundingClientRect();if(rect?.width)position.label={left:rect.left-canvasBox.left,right:rect.right-canvasBox.left,top:rect.top-canvasBox.top,bottom:rect.bottom-canvasBox.top}}
44
47
  const svg=planLinksTemplate(axis,this.tlCanvas.style.height);for(const edge of network.edges){const from=positions.get(edge.from.task.key),to=positions.get(edge.to.task.key);if(!from||!to)continue;const tight=Math.abs(edge.from.early+edge.from.task.end-edge.from.task.start+edge.lag-edge.to.early)<1;const critical=this.view.plan.criticalPath!==false&&network.complete&&edge.from.critical&&edge.to.critical&&tight;planLinkTemplate.call(this,svg,axis,from,to,edge,critical,this.planText("planDependency",{from:edge.from.task.title,to:edge.to.task.title}))}
45
- this.planLinks?.remove();this.planLinks=svg;this.tlCanvas.appendChild(svg);this.tlRoot.dataset.cxPlanComplete=String(network.complete);if(!this.calPhone)this.planFitHeight((this.tlTree.tops[this.tlTree.rows.length]||0)+this.tlHead.offsetHeight+2);this.tlHead.querySelector(".cx-plan-today")?.remove();const now=Date.now();if(this.cal.now&&now>=axis.from&&now<axis.to){const label=h("span","cx-plan-today");setText(label,this.calLabels.calendarToday);label.style.insetInlineStart=axis.x(now)+ "px";this.tlHead.appendChild(label)}
48
+ this.planLinks?.remove();this.planLinks=svg;this.tlCanvas.appendChild(svg);this.tlRoot.dataset.cxPlanComplete=String(network.complete);if(!this.calPhone){const padding=parseFloat(getComputedStyle(this.tlCanvas).paddingBottom)||0;const scrollbar=this.tlMain.offsetHeight-this.tlMain.clientHeight;this.planFitHeight((this.tlTree.tops[this.tlTree.rows.length]||0)+this.tlHead.offsetHeight+padding+scrollbar+2)}
49
+ this.tlHead.querySelector(".cx-plan-today")?.remove();const now=Date.now();if(this.cal.now&&now>=axis.from&&now<axis.to){const label=h("span","cx-plan-today");setText(label,this.calLabels.calendarToday);label.style.insetInlineStart=axis.x(now)+ "px";this.tlHead.appendChild(label)}
46
50
  this.planPaintAgenda(network);this.planPaintProposal()}});const PLAN_AGENDA_PAGE=50;Object.assign(DataGrid.prototype,{planPaintAgenda(network){if(!this.calPhone){this.planAgenda?.remove();this.planAgenda=this.planAgendaState=this.planAgendaModel=null;return}
47
51
  let state=this.planAgendaState;if(!state){state=this.planAgendaState=planAgendaTemplate(this.labels);this.planAgenda=state.root;state.previous.addEventListener("click",()=>{--state.page;this.planPaintAgendaPage()});state.next.addEventListener("click",()=>{++state.page;this.planPaintAgendaPage()})}
48
52
  if(state.root.parentNode!==this.calBody)this.calBody.appendChild(state.root);const old=this.planAgendaModel;if(old?.events===this.calEvents&&old.rows===this.tlTree.rows&&old.network===network){this.planFitAgendaHeight();return}
@@ -6,88 +6,88 @@ body .cx-host.cx-drawer.cx-record-drawer{max-width:var(--cx-size-640px);}
6
6
  .cx-record-btn .cx-ico{width:var(--cx-size-16px);height:var(--cx-size-16px);flex:none;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;}
7
7
  .cx-drawer .cx-record-link{min-height:0;padding:0;border:0;color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));text-decoration:underline;text-underline-offset:var(--cx-size-2px);overflow-wrap:anywhere;}
8
8
  .cx-drawer .cx-record-link:hover{background:transparent;text-decoration-thickness:var(--cx-size-2px);}
9
- .cx-record-trail{display:flex;align-items:center;gap:var(--cx-size-8px);min-width:0;margin:0 0 var(--cx-size-4px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
9
+ .cx-record-trail{display:flex;align-items:center;gap:var(--cx-size-8px);min-width:0;margin:0 0 var(--cx-size-4px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
10
10
  .cx-drawer .cx-record-back{min-height:0;padding:0 var(--cx-size-4px) 0 0;color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));font-weight:600;}
11
11
  .cx-record-crumbs{display:flex;align-items:center;gap:var(--cx-size-4px);min-width:0;margin:0;padding:0;list-style:none;overflow:hidden;}
12
12
  .cx-record-crumbs li{display:flex;align-items:center;gap:var(--cx-size-4px);min-width:0;}
13
13
  .cx-record-crumbs li::before{content:"›";}
14
- .cx-drawer .cx-record-crumb{display:block;max-width:var(--cx-size-160px);min-height:0;padding:0 var(--cx-size-2px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
15
- .cx-record-summary{flex:none;display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-8px) var(--cx-size-20px);padding:var(--cx-size-10px) var(--cx-size-16px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
14
+ .cx-drawer .cx-record-crumb{display:block;max-width:var(--cx-size-160px);min-height:0;padding:0 var(--cx-size-2px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
15
+ .cx-record-summary{flex:none;display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-8px) var(--cx-size-20px);padding:var(--cx-size-10px) var(--cx-size-16px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
16
16
  .cx-record-status{display:flex;align-items:center;gap:var(--cx-size-6px);}
17
17
  .cx-record-facts{display:flex;flex-wrap:wrap;gap:var(--cx-size-6px) var(--cx-size-20px);margin:0;}
18
18
  .cx-record-fact{min-width:0;}
19
- .cx-record-fact dt{font-size:var(--cx-size-11d5px);letter-spacing:var(--cx-size-d04em);text-transform:uppercase;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
19
+ .cx-record-fact dt{font-size:var(--cx-size-11d5px);letter-spacing:var(--cx-size-d04em);text-transform:uppercase;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
20
20
  .cx-record-fact dd{margin:0;font-weight:600;overflow-wrap:anywhere;}
21
21
  .cx-drawer .cx-drawer-h > .cx-record-menu{position:relative;flex:none;}
22
22
  .cx-drawer .cx-record-menu-btn{justify-content:center;width:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));height:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));padding:0;}
23
- .cx-record-menu-list{position:absolute;right:0;top:calc(100% + var(--cx-size-4px));z-index:5;display:flex;flex-direction:column;min-width:var(--cx-size-180px);padding:var(--cx-size-4px);background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-overlay,var(--hfx-radius-lg,10px));box-shadow:var(--hfx-elevation-2,0 1px 2px rgba(22,24,28,.05),0 6px 18px -10px rgba(22,24,28,.18));}
23
+ .cx-record-menu-list{position:absolute;right:0;top:calc(100% + var(--cx-size-4px));z-index:5;display:flex;flex-direction:column;min-width:var(--cx-size-180px);padding:var(--cx-size-4px);background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-overlay,var(--hfx-radius-lg,10px));box-shadow:var(--hfx-elevation-2,0 1px 2px rgba(22,24,28,.05),0 6px 18px -10px rgba(22,24,28,.18));}
24
24
  .cx-record-menu-item{justify-content:flex-start;min-height:var(--cx-size-32px);white-space:nowrap;}
25
- .cx-record-tools{position:sticky;top:0;z-index:3;background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
25
+ .cx-record-tools{position:sticky;top:0;z-index:3;background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
26
26
  .cx-record-tabs{display:flex;gap:var(--cx-size-2px);padding:0 var(--cx-size-10px);overflow-x:auto;scrollbar-width:thin;}
27
- .cx-record-tab{flex:none;padding:var(--cx-size-10px) var(--cx-size-10px) var(--cx-size-8px);border:0;border-bottom:var(--cx-size-2px) solid transparent;background:transparent;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font:inherit;font-weight:600;white-space:nowrap;cursor:pointer;}
28
- .cx-record-tab:hover{color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
29
- .cx-record-tab[aria-selected="true"]{color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));border-bottom-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
27
+ .cx-record-tab{flex:none;padding:var(--cx-size-10px) var(--cx-size-10px) var(--cx-size-8px);border:0;border-bottom:var(--cx-size-2px) solid transparent;background:transparent;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font:inherit;font-weight:600;white-space:nowrap;cursor:pointer;}
28
+ .cx-record-tab:hover{color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
29
+ .cx-record-tab[aria-selected="true"]{color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));border-bottom-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
30
30
  .cx-record-subtools{display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-4px) var(--cx-size-12px);padding:var(--cx-size-6px) var(--cx-size-12px);}
31
- .cx-record-tabs + .cx-record-subtools{border-top:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
31
+ .cx-record-tabs + .cx-record-subtools{border-top:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
32
32
  .cx-record-jump{display:flex;flex-wrap:wrap;gap:var(--cx-size-4px);flex:1;min-width:0;}
33
- .cx-drawer .cx-record-jump-link{min-height:var(--cx-size-24px);padding:0 var(--cx-size-10px);border-color:var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));font-size:var(--cx-size-13px);color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
34
- .cx-drawer .cx-record-empty{margin-inline-start:auto;min-height:var(--cx-size-24px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
35
- .cx-record-section{border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
33
+ .cx-drawer .cx-record-jump-link{min-height:var(--cx-size-24px);padding:0 var(--cx-size-10px);border-color:var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));font-size:var(--cx-size-13px);color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
34
+ .cx-drawer .cx-record-empty{margin-inline-start:auto;min-height:var(--cx-size-24px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
35
+ .cx-record-section{border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
36
36
  .cx-record-section:last-child{border-bottom:0;}
37
- .cx-record-section .cx-record-section{border-bottom:0;margin:0 var(--cx-size-16px) var(--cx-size-4px);border-inline-start:var(--cx-size-2px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
37
+ .cx-record-section .cx-record-section{border-bottom:0;margin:0 var(--cx-size-16px) var(--cx-size-4px);border-inline-start:var(--cx-size-2px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
38
38
  .cx-record-section-h{margin:0;font:inherit;}
39
- .cx-drawer .cx-record-toggle{width:100%;padding:calc(var(--hfx-space-1,0.25rem)*2.5) 0 var(--hfx-space-1,0.25rem);border:0;border-radius:var(--hfx-radius-none,0);font-size:var(--hfx-type-small-size,0.8125rem);font-weight:var(--hfx-weight-semibold,600);letter-spacing:0;text-transform:none;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
39
+ .cx-drawer .cx-record-toggle{width:100%;padding:calc(var(--hfx-space-1,0.25rem)*2.5) 0 var(--hfx-space-1,0.25rem);border:0;border-radius:var(--hfx-radius-none,0);font-size:var(--hfx-type-small-size,0.8125rem);font-weight:var(--hfx-weight-semibold,600);letter-spacing:0;text-transform:none;color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
40
40
  .cx-record-toggle > .cx-record-btn-label{flex:1;min-width:0;text-align:start;order:0;}
41
41
  .cx-record-toggle .cx-ico{width:var(--cx-size-14px);height:var(--cx-size-14px);order:1;margin-inline-start:auto;transform:rotate(90deg);transition:transform .12s;}
42
42
  .cx-record-toggle[aria-expanded="false"] .cx-ico{transform:none;}
43
- .cx-drawer .cx-record-section .cx-record-section .cx-record-toggle{padding:var(--cx-size-6px) var(--cx-size-10px) var(--cx-size-2px);font-size:var(--cx-size-13px);letter-spacing:0;text-transform:none;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
43
+ .cx-drawer .cx-record-section .cx-record-section .cx-record-toggle{padding:var(--cx-size-6px) var(--cx-size-10px) var(--cx-size-2px);font-size:var(--cx-size-13px);letter-spacing:0;text-transform:none;color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
44
44
  .cx-record-section .cx-record-section .cx-dl{padding:var(--cx-size-4px) var(--cx-size-10px) var(--cx-size-6px);}
45
45
  .cx-record-section-b{padding-bottom:var(--cx-size-6px);}
46
46
  .cx-record-section-b > .cx-dl{padding-top:var(--cx-size-6px);padding-bottom:var(--cx-size-6px);}
47
- .cx-record-object{grid-template-columns:minmax(var(--cx-size-92px),max-content) 1fr;gap:var(--cx-size-2px) var(--cx-size-12px);padding:var(--cx-size-2px) 0 var(--cx-size-2px) var(--cx-size-10px);border-inline-start:var(--cx-size-2px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
47
+ .cx-record-object{grid-template-columns:minmax(var(--cx-size-92px),max-content) 1fr;gap:var(--cx-size-2px) var(--cx-size-12px);padding:var(--cx-size-2px) 0 var(--cx-size-2px) var(--cx-size-10px);border-inline-start:var(--cx-size-2px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
48
48
  .cx-drawer .cx-record-object dd{margin-bottom:0;}
49
49
  .cx-record-section-b,.cx-record-object-value{container-type:inline-size;min-width:0;}
50
50
  @container (max-width:400px){
51
51
  .cx-record-object,.cx-record-section-b > .cx-dl{grid-template-columns:minmax(0,1fr);gap:var(--cx-size-2px) 0;}
52
52
  }
53
53
  .cx-record-block{padding:var(--cx-size-6px) var(--cx-size-16px) var(--cx-size-10px);}
54
- .cx-record-block-h{margin-bottom:var(--cx-size-6px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
54
+ .cx-record-block-h{margin-bottom:var(--cx-size-6px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
55
55
  .cx-record-custom{padding:var(--cx-size-6px) var(--cx-size-16px);}
56
56
  .cx-record-custom:empty{display:none;}
57
57
  .cx-record-chips{display:flex;flex-wrap:wrap;gap:var(--cx-size-4px);}
58
58
  .cx-drawer .cx-record-chip{display:inline-flex;align-items:center;max-width:100%;min-height:var(--cx-size-22px);padding:0 var(--cx-size-8px);border:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-status,999px);font-size:var(--cx-size-13px);overflow-wrap:anywhere;text-decoration:none;}
59
- .cx-drawer .cx-record-chip:is(.cx-tone-info,.cx-tone-success,.cx-tone-warning,.cx-tone-danger,.cx-toned){background:color-mix(in srgb,currentColor 9%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));border-color:color-mix(in srgb,currentColor 38%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
59
+ .cx-drawer .cx-record-chip:is(.cx-tone-info,.cx-tone-success,.cx-tone-warning,.cx-tone-danger,.cx-toned){background:color-mix(in srgb,currentColor 9%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));border-color:color-mix(in srgb,currentColor 38%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));}
60
60
  .cx-drawer .cx-record-chip.cx-record-link{color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
61
- .cx-drawer .cx-diff-removed{text-decoration:line-through;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
61
+ .cx-drawer .cx-diff-removed{text-decoration:line-through;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
62
62
  .cx-drawer .cx-diff-added{font-weight:600;border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
63
- .cx-record-more-count{margin-inline-start:var(--cx-size-4px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-12d5px);}
64
- .cx-drawer :is(.cx-record-more,.cx-record-load-more,.cx-record-retry){margin-top:var(--cx-size-6px);border-color:var(--hfx-color-border,light-dark(#e2e4e7,#272a30));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
63
+ .cx-record-more-count{margin-inline-start:var(--cx-size-4px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-size:var(--cx-size-12d5px);}
64
+ .cx-drawer :is(.cx-record-more,.cx-record-load-more,.cx-record-retry){margin-top:var(--cx-size-6px);border-color:var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
65
65
  :is(.cx-record-diff,.cx-record-table){width:100%;border-collapse:collapse;font-size:var(--cx-size-13px);}
66
- :is(.cx-record-diff,.cx-record-table) :is(th,td){padding:var(--cx-size-4px) var(--cx-size-8px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));text-align:start;vertical-align:top;overflow-wrap:anywhere;}
67
- :is(.cx-record-diff,.cx-record-table) thead th{font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
66
+ :is(.cx-record-diff,.cx-record-table) :is(th,td){padding:var(--cx-size-4px) var(--cx-size-8px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));text-align:start;vertical-align:top;overflow-wrap:anywhere;}
67
+ :is(.cx-record-diff,.cx-record-table) thead th{font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
68
68
  .cx-record-diff tbody th{width:30%;font-weight:600;}
69
- .cx-record-diff .cx-diff-before{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
69
+ .cx-record-diff .cx-diff-before{color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
70
70
  .cx-record-diff-compact{margin-top:var(--cx-size-6px);}
71
71
  .cx-record-diff-compact thead{display:none;}
72
- .cx-record-collection-h{display:flex;align-items:center;gap:var(--cx-size-8px);margin-bottom:var(--cx-size-6px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
72
+ .cx-record-collection-h{display:flex;align-items:center;gap:var(--cx-size-8px);margin-bottom:var(--cx-size-6px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
73
73
  .cx-drawer .cx-record-open-all{margin-inline-start:auto;color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));font-weight:600;}
74
- .cx-record-nested{height:var(--cx-size-360px);border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
74
+ .cx-record-nested{height:var(--cx-size-360px);border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
75
75
  .cx-record-nested.cx-host{padding:0;}
76
- .cx-record-card{margin-bottom:var(--cx-size-8px);padding:var(--cx-size-8px) var(--cx-size-12px);border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
76
+ .cx-record-card{margin-bottom:var(--cx-size-8px);padding:var(--cx-size-8px) var(--cx-size-12px);border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
77
77
  .cx-record-card-title{font-weight:600;}
78
78
  .cx-drawer .cx-record-card .cx-dl{grid-template-columns:1fr;gap:0;padding:var(--cx-size-4px) 0 0;}
79
- .cx-record-card dt{font-size:var(--cx-size-12px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
79
+ .cx-record-card dt{font-size:var(--cx-size-12px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
80
80
  .cx-drawer .cx-record-card dd{margin-bottom:var(--cx-size-4px);}
81
81
  .cx-timeline{position:relative;margin:0;padding:0;list-style:none;}
82
- .cx-timeline-day{padding:var(--cx-size-8px) 0 var(--cx-size-2px);font-size:var(--cx-size-11d5px);font-weight:700;letter-spacing:var(--cx-size-d04em);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
82
+ .cx-timeline-day{padding:var(--cx-size-8px) 0 var(--cx-size-2px);font-size:var(--cx-size-11d5px);font-weight:700;letter-spacing:var(--cx-size-d04em);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
83
83
  .cx-timeline-item{position:relative;display:grid;grid-template-columns:var(--cx-size-16px) 1fr;gap:var(--cx-size-8px);padding:var(--cx-size-4px) 0 var(--cx-size-8px);}
84
- .cx-timeline-item::before{content:"";position:absolute;left:calc(var(--cx-size-8px) - var(--cx-size-1px));top:var(--cx-size-20px);bottom:0;width:var(--cx-size-2px);background:var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
84
+ .cx-timeline-item::before{content:"";position:absolute;left:calc(var(--cx-size-8px) - var(--cx-size-1px));top:var(--cx-size-20px);bottom:0;width:var(--cx-size-2px);background:var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
85
85
  .cx-timeline-item:last-child::before{display:none;}
86
- .cx-timeline-dot{width:var(--cx-size-10px);height:var(--cx-size-10px);margin:var(--cx-size-5px) auto 0;border-radius:50%;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));background:currentColor;}
86
+ .cx-timeline-dot{width:var(--cx-size-10px);height:var(--cx-size-10px);margin:var(--cx-size-5px) auto 0;border-radius:50%;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));background:currentColor;}
87
87
  .cx-timeline-dot:is(.cx-tone-info,.cx-tone-success,.cx-tone-warning,.cx-tone-danger,.cx-toned){color:var(--cx-t,inherit);}
88
- .cx-timeline-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-6px);font-size:var(--cx-size-12d5px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
88
+ .cx-timeline-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-6px);font-size:var(--cx-size-12d5px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
89
89
  .cx-timeline-summary{margin-top:var(--cx-size-2px);overflow-wrap:anywhere;}
90
- .cx-record-note{margin:var(--cx-size-8px) var(--cx-size-16px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-style:italic;}
90
+ .cx-record-note{margin:var(--cx-size-8px) var(--cx-size-16px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-style:italic;}
91
91
  .cx-record-error{display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-8px);color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));font-style:normal;}
92
92
  .cx-drawer.cx-phone :is(.cx-record-btn,.cx-record-tab){min-height:var(--cx-size-44px);}
93
93
  .cx-drawer.cx-phone .cx-record-menu-btn{width:var(--cx-size-44px);height:var(--cx-size-44px);}
@@ -95,26 +95,31 @@ body .cx-host.cx-drawer.cx-record-drawer{max-width:var(--cx-size-640px);}
95
95
  .cx-drawer.cx-phone :is(.cx-record-link,.cx-record-crumb){min-height:var(--cx-size-24px);}
96
96
  .cx-drawer.cx-phone .cx-record-nested{height:var(--cx-size-280px);}
97
97
  .cx-drawer.cx-phone .cx-record-section .cx-record-section{margin-inline:var(--cx-size-10px);}
98
+ .cx-drawer.cx-phone .cx-record-subtools{flex-direction:column;align-items:stretch;}
99
+ .cx-drawer.cx-phone .cx-record-jump{flex:none;flex-wrap:nowrap;width:100%;box-sizing:border-box;overflow-x:auto;scroll-snap-type:x proximity;scrollbar-width:thin;padding-block:var(--hfx-space-0-5,2px);padding-inline-end:var(--hfx-space-4,1rem);mask-image:linear-gradient(to right,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))) calc(100% - var(--hfx-space-4,1rem)),transparent);}
100
+ .cx-drawer.cx-phone .cx-record-jump:dir(rtl){mask-image:linear-gradient(to left,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))) calc(100% - var(--hfx-space-4,1rem)),transparent);}
101
+ .cx-drawer.cx-phone .cx-record-jump-link{flex:none;white-space:nowrap;scroll-snap-align:start;}
102
+ .cx-drawer.cx-phone .cx-record-empty{align-self:flex-start;margin-inline-start:0;}
98
103
  .cx-record-print{display:none;}
99
104
  @media print{
100
105
  html.cx-record-printing body > :not(.cx-record-print){display:none !important;}
101
- html.cx-record-printing .cx-record-print{display:block;padding:0;font:var(--cx-size-12px)/1.4 var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
106
+ html.cx-record-printing .cx-record-print{display:block;padding:0;font:var(--cx-size-12px)/1.4 var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
102
107
  .cx-record-print h1{margin:0 0 var(--cx-size-4px);font-size:var(--cx-size-20px);}
103
108
  .cx-record-print h2{margin:var(--cx-size-16px) 0 var(--cx-size-4px);font-size:var(--cx-size-16px);}
104
109
  .cx-record-print .cx-record-section{break-inside:avoid;border:0;}
105
- .cx-record-print .cx-record-section-h{margin:var(--cx-size-10px) 0 var(--cx-size-2px);font-size:var(--cx-size-11d5px);font-weight:700;text-transform:uppercase;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
110
+ .cx-record-print .cx-record-section-h{margin:var(--cx-size-10px) 0 var(--cx-size-2px);font-size:var(--cx-size-11d5px);font-weight:700;text-transform:uppercase;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
106
111
  .cx-record-print .cx-dl{display:grid;grid-template-columns:var(--cx-size-180px) 1fr;gap:var(--cx-size-2px) var(--cx-size-12px);margin:0;padding:0;}
107
112
  .cx-record-print dd{margin:0;}
108
- .cx-record-print .p-sub{margin-inline-start:var(--cx-size-6px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
109
- .cx-record-print .cx-record-summary{border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
113
+ .cx-record-print .p-sub{margin-inline-start:var(--cx-size-6px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
114
+ .cx-record-print .cx-record-summary{border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
110
115
  }
111
116
  @media (prefers-reduced-motion:reduce){.cx-record-toggle .cx-ico{transition:none;}}
112
117
  @media (forced-colors:active){.cx-record-tab[aria-selected="true"]{border-bottom-color:Highlight;}.cx-timeline-dot{forced-color-adjust:none;background:CanvasText;}}
113
- .cx-record-footer{flex:none;display:flex;justify-content:flex-end;gap:var(--hfx-space-2,0.5rem);padding:var(--hfx-space-3,0.75rem) var(--hfx-space-4,1rem);border-top:var(--hfx-border-width,1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
118
+ .cx-record-footer{flex:none;display:flex;justify-content:flex-end;gap:var(--hfx-space-2,0.5rem);padding:var(--hfx-space-3,0.75rem) var(--hfx-space-4,1rem);border-top:var(--hfx-border-width,1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
114
119
  .cx-record-footer .cx-record-primary{color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
115
- .cx-record-footer .cx-record-primary:disabled{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-color:var(--hfx-color-border,light-dark(#e2e4e7,#272a30));cursor:wait;}
116
- .cx-record-subtitle{margin:var(--hfx-space-1,0.25rem) 0 0;font-size:var(--hfx-type-small-size,0.8125rem);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
117
- .cx-record-drawer .cx-dl dt{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--hfx-type-caption-size,0.75rem);font-weight:normal;}
120
+ .cx-record-footer .cx-record-primary:disabled{color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-color:var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));cursor:wait;}
121
+ .cx-record-subtitle{margin:var(--hfx-space-1,0.25rem) 0 0;font-size:var(--hfx-type-small-size,0.8125rem);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
122
+ .cx-record-drawer .cx-dl dt{color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-size:var(--hfx-type-caption-size,0.75rem);font-weight:normal;}
118
123
  .cx-record-drawer .cx-dl dd{font-size:var(--hfx-type-body-size,0.875rem);}
119
124
  .cx-drawer.cx-record-drawer .cx-drawer-h h4{width:auto;max-width:100%;overflow-wrap:anywhere;}
120
125
  .cx-drawer.cx-record-drawer .cx-drawer-h > :not(:first-child){flex:none;margin-inline:0;}
@@ -1,4 +1,4 @@
1
- (function(global){"use strict";const installed=new WeakSet();const part={version:"2a4059ade4ca1439",requires:["ui-menu"],install(context){if(installed.has(context.RECORD_IMPL))return;const{RECORD_IMPL,UI_IMPL,TreeGrid,h,setText,fill,cellText,cellValue,isCellObject,formatValue,toneOf,applyTone,toneColors,validateGridRows,badgeElement,loadSidecar,requireIdentifier,PROTOCOL,foldText,createTreeGrid,svgIcon,gridExportField,columnNumericTone,columnValueTone,validateColumnValues}=context;function changeCellText(cell,column,fmt){if(cell==null)return "—";const structured=isCellObject(cell)&&["items","fields","records","events","changes"].some(name=>cell[name]);if(isCellObject(cell)&&cellValue(cell)==null&&!cell.text&&!structured)return "null";const text=cellText(cell,column,fmt);return text.length?text:'""'}
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"cb6bcd1baf644a51",requires:["ui-menu"],install(context){if(installed.has(context.RECORD_IMPL))return;const{RECORD_IMPL,UI_IMPL,TreeGrid,h,setText,fill,cellText,cellValue,isCellObject,formatValue,toneOf,applyTone,toneColors,validateGridRows,badgeElement,loadSidecar,requireIdentifier,PROTOCOL,foldText,createTreeGrid,svgIcon,gridExportField,columnNumericTone,columnValueTone,validateColumnValues}=context;function changeCellText(cell,column,fmt){if(cell==null)return "—";const structured=isCellObject(cell)&&["items","fields","records","events","changes"].some(name=>cell[name]);if(isCellObject(cell)&&cellValue(cell)==null&&!cell.text&&!structured)return "null";const text=cellText(cell,column,fmt);return text.length?text:'""'}
2
2
  const RECORD_KINDS=["items","fields","records","events","changes"],RECORD_LINK_KEY=/^[A-Za-z][\w.-]{0,31}$/, RECORD_MAX_STRUCTURE_DEPTH = 8;
3
3
  const recordKind=cell=>{const kinds=isCellObject(cell)&&!Array.isArray(cell)?RECORD_KINDS.filter(name=>cell[name]!==undefined):[];if(kinds.length>1)recordFail("a cell carries at most one structured value.");return kinds[0]||null};const recordFail=message=>{throw new Error("CanopyX: "+message)};const recordText=(value,max=256)=>typeof value==="string"&&!!value.trim()&&value.length<=max;const recordGridHelpers=()=>RECORD_IMPL.grid||{};function recordCheckValue(cell,depth=0){if(cell==null)return;if(depth>RECORD_MAX_STRUCTURE_DEPTH)recordFail("structured values nest at most "+RECORD_MAX_STRUCTURE_DEPTH+" levels.");const kind=recordKind(cell);if(kind==="items")for(const item of cell.items||[])recordCheckValue(item,depth+1);if(kind==="fields")for(const field of cell.fields||[])recordCheckValue(field.value,depth+1);if(kind==="changes")for(const change of cell.changes||[]){recordCheckValue(change.before,depth+1);recordCheckValue(change.after,depth+1)}
4
4
  if(kind==="events")for(const event of cell.events||[])for(const change of event.changes||[]){recordCheckValue(change.before,depth+1);recordCheckValue(change.after,depth+1)}
@@ -100,7 +100,8 @@ for(const change of changes){if(!change||!recordText(change.name,4096))recordFai
100
100
  line.append(name,before,after);body.appendChild(line)}
101
101
  const thead=h("thead");thead.appendChild(head);table.append(caption,thead,body);element.appendChild(table)}
102
102
  let RECORD_SHOW_EMPTY=false;const recordId=(dialog,kind,id)=>dialog.id+"-"+kind+"-"+String(id).replace(/[^\w-]/g, "_");
103
- const recordOnDispose=(signal,cleanup)=>{const dispose=()=>{try{cleanup()}catch(error){console.error(error)}};if(signal.aborted)dispose();else signal.addEventListener("abort",dispose,{once:true})};function recordContext(view,record,dialog,context,payload){const ctx={view,record,payload,dialog,labels:view.labels,fmt:view.fmt,signal:context.signal,index:context.index,origins:0,pending:[],phone:view.host.clientWidth<=640,print:!!context.print,width:context.print?520:view.host.clientWidth<=640?300:380,row:{id:record.id,cells:recordMerge(record.cells,payload?.cells,record.fields,payload?.fields)},node:view.kind==="tree"?{...record,cells:recordMerge(record.cells,payload?.cells)}:null};ctx.navigate=(ref,origin)=>recordNavigate(ctx,ref,origin);ctx.repaint=()=>{if(!context.signal.aborted&&dialog._cxRecord===record&&dialog.isConnected)recordRepaint(view,dialog,record,context.index)};return ctx}
103
+ const recordOnDispose=(signal,cleanup)=>{const dispose=()=>{try{cleanup()}catch(error){console.error(error)}};if(signal.aborted)dispose();else signal.addEventListener("abort",dispose,{once:true})};const recordJump=(body,tools,section,instant)=>{const top=section.getBoundingClientRect().top-body.getBoundingClientRect().top+body.scrollTop -(tools.isConnected?tools.offsetHeight:0);const reduce=global.matchMedia?.("(prefers-reduced-motion: reduce)").matches;body.scrollTo({top:Math.max(0,Math.round(top)),behavior:reduce||instant?"instant":"smooth"})};const recordTrail=(sections,id)=>{for(const section of sections){if(section.id===id)return[id];const inner=recordTrail(section.sections,id);if(inner)return[section.id,...inner]}
104
+ return null};function recordContext(view,record,dialog,context,payload){const ctx={view,record,payload,dialog,labels:view.labels,fmt:view.fmt,signal:context.signal,index:context.index,origins:0,pending:[],phone:view.host.clientWidth<=640,print:!!context.print,width:context.print?520:view.host.clientWidth<=640?300:380,row:{id:record.id,cells:recordMerge(record.cells,payload?.cells,record.fields,payload?.fields)},node:view.kind==="tree"?{...record,cells:recordMerge(record.cells,payload?.cells)}:null};ctx.navigate=(ref,origin)=>recordNavigate(ctx,ref,origin);ctx.repaint=()=>{if(!context.signal.aborted&&dialog._cxRecord===record&&dialog.isConnected)recordRepaint(view,dialog,record,context.index)};return ctx}
104
105
  function recordMerge(...sources){const cells=Object.create(null);for(const source of sources)if(source)for(const key of Object.keys(source))if(key!=="__proto__")cells[key]=source[key];return cells}
105
106
  function recordRepaint(view,dialog,record,index){const body=dialog.querySelector(".cx-drawer-body"),scroll=body?.scrollTop||0,active=document.activeElement,inside=body?.contains(active);const section=inside&&active.closest("[data-cx-section]")?.getAttribute("data-cx-section"),field=inside&&active.closest("[data-cx-field]")?.getAttribute("data-cx-field");const kind=inside&&[...active.classList].find(name=>name.startsWith("cx-record-")),id=inside&&active.id;dialog._cxPaint(record,index);if(body)body.scrollTop=scroll;if(!inside||body.contains(document.activeElement))return;const scope=field?body.querySelector('[data-cx-field="'+CSS.escape(field)+ '"]'):section?body.querySelector('[data-cx-section="'+CSS.escape(section)+ '"]'):body;const title=dialog.querySelector(".cx-drawer-h h4"),target=id&&body.querySelector("#"+CSS.escape(id))||kind&&scope?.querySelector("."+kind)||title;if(target===title)view.focusRing(title);else target?.focus({preventScroll:true})}
106
107
  const recordVisible=(ctx,field,cell,showEmpty)=>showEmpty||!recordEmpty(cell,field,ctx.fmt)||ctx.view.recordKeepField?.(field.id,ctx.record)===true;function recordHasContent(ctx,section,showEmpty){return!!section.renderer||section.fields.some(field=>recordVisible(ctx,field,recordCell(ctx.view,ctx.record,ctx.payload,field),showEmpty))||
@@ -122,12 +123,14 @@ RECORD_IMPL.paint=(view,record,body,dialog,context)=>{const state=dialog._cxPane
122
123
  state.index=context.index;let layout;try{layout=recordLayout(view,recordFields(view))}
123
124
  catch(error){view.emit("error",{error});return view.paintDrawerBody.call(Object.create(view,{recordNeeded:{value:()=>false}}),record,body,dialog,context)}
124
125
  const entry=recordEnsure(view,record.id),payload=entry?.state==="ready"?entry.payload:null,ctx=recordContext(view,record,dialog,context,payload);if(view.loadHistory&&!view._recordHistory&&(view.view.record?.fields||[]).some(field=>["statusStrip","sparklineBars","sparklineLine"].includes(field.presenter?.kind)))
125
- view._recordHistory=Promise.resolve(view.loadHistory()).then(()=>{if(dialog.isConnected&&dialog._cxRecord)recordRepaint(view,dialog,dialog._cxRecord,dialog._cxPanel?.index)},()=>{});const showEmpty=RECORD_SHOW_EMPTY||!layout.hideEmpty;const tabs=layout.tabs.filter(tab=>tab.sections.some(section=>recordHasContent(ctx,section,showEmpty)));if(!tabs.length)tabs.push(layout.tabs[0]);if(!tabs.some(tab=>tab.id===state.tab))state.tab=tabs[0].id;recordSummary(ctx,layout,dialog);body.replaceChildren();const tools=h("div","cx-record-tools"),panel=h("div","cx-record-panel"),sub=h("div","cx-record-subtools");let tabLifetime,tabContext;const paintTab=()=>{tabLifetime?.abort();tabLifetime=new AbortController();tabContext=recordContext(view,record,dialog,{...context,signal:AbortSignal.any([context.signal,tabLifetime.signal])},payload);const tab=tabs.find(item=>item.id===state.tab),sections=tab.sections.map(section=>recordSection(tabContext,section,state,showEmpty)).filter(Boolean);panel.replaceChildren(...sections);sub.replaceChildren();if(tabs.length>1){panel.setAttribute("role","tabpanel");panel.id=recordId(dialog,"p",tab.id);panel.setAttribute("aria-labelledby",recordId(dialog,"t",tab.id));panel.tabIndex=0}
126
- if(layout.jump!==false&&sections.length>=(layout.jump?2:4)){const jump=h("nav","cx-record-jump");jump.setAttribute("aria-label",ctx.labels.recordSections);for(const element of sections){const target=element.querySelector(".cx-record-toggle");jump.appendChild(recordButton(target.textContent,()=>{element.scrollIntoView({block:"start"});target.focus({preventScroll:true})},"cx-record-jump-link"))}
126
+ view._recordHistory=Promise.resolve(view.loadHistory()).then(()=>{if(dialog.isConnected&&dialog._cxRecord)recordRepaint(view,dialog,dialog._cxRecord,dialog._cxPanel?.index)},()=>{});const showEmpty=RECORD_SHOW_EMPTY||!layout.hideEmpty;const tabs=layout.tabs.filter(tab=>tab.sections.some(section=>recordHasContent(ctx,section,showEmpty)));if(!tabs.length)tabs.push(layout.tabs[0]);const owner=state.jump&&tabs.find(tab=>recordTrail(tab.sections,state.jump));if(owner){state.tab=owner.id;for(const id of recordTrail(owner.sections,state.jump))state.collapsed.set(id,false)}
127
+ if(!tabs.some(tab=>tab.id===state.tab))state.tab=tabs[0].id;recordSummary(ctx,layout,dialog);body.replaceChildren();const tools=h("div","cx-record-tools"),panel=h("div","cx-record-panel"),sub=h("div","cx-record-subtools");let tabLifetime,tabContext;const paintTab=()=>{tabLifetime?.abort();tabLifetime=new AbortController();tabContext=recordContext(view,record,dialog,{...context,signal:AbortSignal.any([context.signal,tabLifetime.signal])},payload);const tab=tabs.find(item=>item.id===state.tab),sections=tab.sections.map(section=>recordSection(tabContext,section,state,showEmpty)).filter(Boolean);panel.replaceChildren(...sections);sub.replaceChildren();if(tabs.length>1){panel.setAttribute("role","tabpanel");panel.id=recordId(dialog,"p",tab.id);panel.setAttribute("aria-labelledby",recordId(dialog,"t",tab.id));panel.tabIndex=0}
128
+ if(layout.jump!==false&&sections.length>=(layout.jump?2:4)){const jump=h("nav","cx-record-jump");jump.setAttribute("aria-label",ctx.labels.recordSections);for(const element of sections){const target=element.querySelector(".cx-record-toggle");jump.appendChild(recordButton(target.textContent,()=>{recordJump(body,tools,element);target.focus({preventScroll:true})},"cx-record-jump-link"))}
127
129
  sub.appendChild(jump)}
128
130
  const hidden=layout.hideEmpty?recordEmptyCount(ctx,layout.tabs.flatMap(item=>item.sections)):0;if(hidden||RECORD_SHOW_EMPTY&&layout.hideEmpty){const toggle=recordButton(RECORD_SHOW_EMPTY?ctx.labels.recordHideEmpty:fill(ctx.labels.recordShowEmpty,{count:recordCount(ctx,hidden)}),()=>{RECORD_SHOW_EMPTY=!RECORD_SHOW_EMPTY;recordRepaint(view,dialog,record,context.index);dialog.querySelector(".cx-record-empty")?.focus()},"cx-record-empty");toggle.setAttribute("aria-pressed",String(RECORD_SHOW_EMPTY));sub.appendChild(toggle)}
129
131
  sub.hidden=!sub.firstChild};const select=(id,focus)=>{state.tab=id;for(const button of tools.querySelectorAll("[role=tab]")){const on=button.id===recordId(dialog,"t",id);button.setAttribute("aria-selected",String(on));button.tabIndex=on?0:-1;if(on)button.setAttribute("aria-controls",recordId(dialog,"p",id));else button.removeAttribute("aria-controls")}
130
- paintTab();recordMount(tabContext,panel);dialog.dispatchEvent(new CustomEvent("cx-drawer-paint",{detail:{id:record.id,index:context.index??null}}));if(focus)tools.querySelector("[aria-selected=true]")?.focus()};if(tabs.length>1)tools.appendChild(recordTabs(ctx,layout,state,tabs,select));tools.appendChild(sub);paintTab();body.append(tools,panel);tools.hidden=tabs.length<2&&sub.hidden;if(entry?.state==="loading"){const note=h("p","cx-record-note");setText(note,ctx.labels.loading);panel.prepend(note);entry.promise.then(()=>ctx.repaint(),()=>ctx.repaint())}else if(entry?.state==="error"){const note=h("p","cx-record-note cx-record-error");setText(note,fill(ctx.labels.recordLoadFailed,{error:entry.error.message}));note.setAttribute("role","alert");note.appendChild(recordButton(ctx.labels.recordRetry,()=>{view._recordPayloads.delete(recordCacheKey(view,record.id));ctx.repaint()},"cx-record-retry"));panel.prepend(note)}
132
+ paintTab();recordMount(tabContext,panel);dialog.dispatchEvent(new CustomEvent("cx-drawer-paint",{detail:{id:record.id,index:context.index??null}}));if(focus)tools.querySelector("[aria-selected=true]")?.focus()};if(tabs.length>1)tools.appendChild(recordTabs(ctx,layout,state,tabs,select));tools.appendChild(sub);paintTab();body.append(tools,panel);body.style.paddingBlockStart="0px";tools.hidden=tabs.length<2&&sub.hidden;if(state.jump&&entry?.state!=="loading"){const jump=state.jump,find=()=>body.querySelector('[data-cx-section="'+CSS.escape(jump)+ '"]');if(find())global.requestAnimationFrame(()=>{const target=find();if(state.jump!==jump||!target)return;state.jump=null;recordJump(body,body.querySelector(".cx-record-tools")||tools,target,true)});else state.jump=null}
133
+ if(entry?.state==="loading"){const note=h("p","cx-record-note");setText(note,ctx.labels.loading);panel.prepend(note);entry.promise.then(()=>ctx.repaint(),()=>ctx.repaint())}else if(entry?.state==="error"){const note=h("p","cx-record-note cx-record-error");setText(note,fill(ctx.labels.recordLoadFailed,{error:entry.error.message}));note.setAttribute("role","alert");note.appendChild(recordButton(ctx.labels.recordRetry,()=>{view._recordPayloads.delete(recordCacheKey(view,record.id));ctx.repaint()},"cx-record-retry"));panel.prepend(note)}
131
134
  recordLinkWrite(view,record,dialog)};function recordSummary(ctx,layout,dialog){const box=dialog.querySelector(".cx-record-summary");if(!box)return;box.replaceChildren();const header=layout.header,value=id=>{const field=layout.byId.get(id);return field&&[field,recordCell(ctx.view,ctx.record,ctx.payload,field)]};if(header?.status){const[field,cell]=value(header.status)||[];if(field&&!recordEmpty(cell,field,ctx.fmt)){const status=h("div","cx-record-status");status.setAttribute("data-cx-fact",field.id);recordValue(ctx,field,cell,status);box.appendChild(status)}}
132
135
  const facts=h("dl","cx-record-facts");for(const id of header?.facts||[]){const[field,cell]=value(id)||[];if(!field||recordEmpty(cell,field,ctx.fmt))continue;const item=h("div","cx-record-fact"),term=h("dt"),detail=h("dd");item.setAttribute("data-cx-fact",field.id);setText(term,field.title);recordValue(ctx,field,cell,detail);item.append(term,detail);facts.appendChild(item)}
133
136
  if(facts.firstChild)box.appendChild(facts);box.hidden=!box.firstChild}
@@ -146,18 +149,22 @@ if(!row)recordFail("record "+id+" is not available.");const returnFocus=options.
146
149
  return view.openGridDrawer(row,index,returnFocus,options)}
147
150
  async function recordOpenNode(view,id,options){await view.requirePart("tree-tools");let w=view.keyMap.get(id);if(!w&&Array.isArray(options.path)&&options.path.length){await view.expandPath(options.path,{focus:false});w=view.keyMap.get(id)}
148
151
  if(!w)recordFail("record "+id+" is not available.");return view.showDetails(id,{...options,node:w.h})}
149
- const recordLinkKey=view=>view.view.record?.deepLink?.key||"record";const recordLinkParams=()=>(global.location.hash||"").replace(/^#/, "").split("&").filter(Boolean);
152
+ const recordLinkKey=view=>view.view.record?.deepLink?.key||"record";const recordSectionPrefix=view=>recordLinkKey(view)+ "Section="+encodeURIComponent(view.view.id)+ ":";function recordLinkSection(view){const prefix=recordSectionPrefix(view),param=recordLinkParams().find(item=>item.startsWith(prefix));try{return param&&decodeURIComponent(param.slice(prefix.length))||null}
153
+ catch(error){return null}}
154
+ const recordLinkParams=()=>(global.location.hash||"").replace(/^#/, "").split("&").filter(Boolean);
150
155
  const recordLinkPath=ids=>ids.map(encodeURIComponent).join("/");function recordLinkRead(view){const prefix=recordLinkKey(view)+ "=";for(const param of recordLinkParams()){const value=param.startsWith(prefix)?param.slice(prefix.length):"",at=value.indexOf(":");if(at<1)continue;try{if(decodeURIComponent(value.slice(0,at))!==view.view.id)continue;const rest=value.slice(at+1),ids=(view.kind==="tree"?rest.split("/"):[rest]).map(decodeURIComponent);if(ids.every(id=>id))return ids}catch(error){}}
151
156
  return null}
152
157
  function recordLinkFor(view,record){const ids=[];if(view.kind==="tree")for(let w=view.keyMap.get(record.id);w&&w!==view.root&&w.key!=null;w=w.parent)ids.unshift(w.key);return recordLinkKey(view)+ "="+encodeURIComponent(view.view.id)+ ":"+recordLinkPath(ids.length?ids:[record.id])}
153
158
  const recordLinkPrefix=view=>recordLinkKey(view)+ "="+encodeURIComponent(view.view.id)+ ":";function recordAddress(view,record){const prefix=recordLinkPrefix(view),params=recordLinkParams().filter(param=>!param.startsWith(prefix));params.push(recordLinkFor(view,record));return global.location.href.replace(/#.*$/, "") + "#" + params.join("&");
154
159
  }
155
- function recordLinkWrite(view,record,dialog){if(!view.view.record?.deepLink)return;const link=record&&recordLinkFor(view,record);view._recordLinkOwner=record?{dialog,link}:null;const prefix=recordLinkPrefix(view),params=recordLinkParams().filter(param=>!param.startsWith(prefix));if(record)params.push(link);const hash=params.length?"#"+params.join("&"):"";if((global.location.hash||"")===hash)return;try{global.history.replaceState(global.history.state,"",hash||global.location.pathname+global.location.search)}
160
+ function recordLinkWrite(view,record,dialog){if(!view.view.record?.deepLink)return;const link=record&&recordLinkFor(view,record);view._recordLinkOwner=record?{dialog,link}:null;const prefix=recordLinkPrefix(view),section=recordSectionPrefix(view),params=recordLinkParams().filter(param=>!param.startsWith(prefix)&&!param.startsWith(section));if(record)params.push(link);const hash=params.length?"#"+params.join("&"):"";if((global.location.hash||"")===hash)return;try{global.history.replaceState(global.history.state,"",hash||global.location.pathname+global.location.search)}
156
161
  catch(error){}
157
162
  view._recordLinkOpen=record?recordLinkPath(recordLinkRead(view)||[]):null}
158
163
  RECORD_IMPL.start=view=>{if(view._recordStarted||!view.view.record?.deepLink)return;view._recordStarted=true;const read=()=>{const ids=recordLinkRead(view),key=ids?recordLinkPath(ids):null,owner=view._recordLinkOwner?.dialog;if(!ids){view._recordLinkOpen=null;view._recordLinkOwner=null;return}
159
- if(key===view._recordLinkOpen&&(!owner||owner.open||owner._replaced))return;view._recordLinkOwner=null;view._recordLinkOpen=key;RECORD_IMPL.open(view,ids[ids.length-1],{path:ids}).catch(error=>view.emit("error",{error}))};global.addEventListener("hashchange",read,{signal:view.lifetime.signal});view.lifetime.signal.addEventListener("abort",()=>{view._recordLinkOwner=null;view._recordLinkOpen=null},{once:true});Promise.resolve(view.ready).then(read,()=>{})};RECORD_IMPL.decorate=(view,dialog,{head,identity,options})=>{if(!view.view.record)return;try{recordSpec(view)}catch(error){return}
160
- dialog.id||=view.id+"-record";dialog.classList.add("cx-record-drawer");const state=dialog._cxPanel={stack:Array.isArray(options.stack)?options.stack:[],tab:options.tab||null,collapsed:new Map()},labels=view.labels;const live=h("div","cx-record-live cx-sr-only");live.setAttribute("aria-live","polite");dialog.appendChild(live);if(state.stack.length){const trail=h("nav","cx-record-trail"),crumbs=h("ol","cx-record-crumbs"),last=state.stack[state.stack.length-1];trail.setAttribute("aria-label",labels.recordTrail);const back=recordButton(labels.recordBack,()=>recordBack(view,dialog),"cx-record-back","back");back.setAttribute("aria-label",fill(labels.recordBackTo,{record:last.title||last.id}));state.stack.slice(-3).forEach((entry,at,list)=>{const item=h("li");item.appendChild(recordButton(entry.title||entry.id,()=>recordBack(view,dialog,list.length-at),"cx-record-crumb"));crumbs.appendChild(item)});trail.append(back,crumbs);identity.prepend(trail)}
164
+ if(key===view._recordLinkOpen&&(!owner||owner.open||owner._replaced)){const section=recordLinkSection(view);if(section&&owner?.open&&owner._cxPanel&&owner._cxRecord){owner._cxPanel.jump=section;recordRepaint(view,owner,owner._cxRecord,owner._cxPanel.index);recordLinkWrite(view,owner._cxRecord,owner)}
165
+ return}
166
+ view._recordLinkOwner=null;view._recordLinkOpen=key;const section=recordLinkSection(view);RECORD_IMPL.open(view,ids[ids.length-1],section?{path:ids,section}:{path:ids}).catch(error=>view.emit("error",{error}))};global.addEventListener("hashchange",read,{signal:view.lifetime.signal});view.lifetime.signal.addEventListener("abort",()=>{view._recordLinkOwner=null;view._recordLinkOpen=null},{once:true});Promise.resolve(view.ready).then(read,()=>{})};RECORD_IMPL.decorate=(view,dialog,{head,identity,options})=>{if(!view.view.record)return;try{recordSpec(view)}catch(error){return}
167
+ dialog.id||=view.id+"-record";dialog.classList.add("cx-record-drawer");const state=dialog._cxPanel={stack:Array.isArray(options.stack)?options.stack:[],tab:options.tab||null,jump:typeof options.section==="string"&&options.section||null,collapsed:new Map()},labels=view.labels;const live=h("div","cx-record-live cx-sr-only");live.setAttribute("aria-live","polite");dialog.appendChild(live);if(state.stack.length){const trail=h("nav","cx-record-trail"),crumbs=h("ol","cx-record-crumbs"),last=state.stack[state.stack.length-1];trail.setAttribute("aria-label",labels.recordTrail);const back=recordButton(labels.recordBack,()=>recordBack(view,dialog),"cx-record-back","back");back.setAttribute("aria-label",fill(labels.recordBackTo,{record:last.title||last.id}));state.stack.slice(-3).forEach((entry,at,list)=>{const item=h("li");item.appendChild(recordButton(entry.title||entry.id,()=>recordBack(view,dialog,list.length-at),"cx-record-crumb"));crumbs.appendChild(item)});trail.append(back,crumbs);identity.prepend(trail)}
161
168
  const summary=h("div","cx-record-summary");summary.hidden=true;head.after(summary);let projectedSubtitle;if(typeof view.opts.recordHeading==="function")dialog.addEventListener("cx-drawer-paint",()=>{if(projectedSubtitle){setText(projectedSubtitle,"");projectedSubtitle.hidden=true}
162
169
  try{const heading=view.opts.recordHeading(Object.freeze(JSON.parse(JSON.stringify(dialog._cxRecord))));if(heading&&typeof heading.title==="string"&&heading.title.length<=512)setText(identity.querySelector("h4"),heading.title);if(heading&&typeof heading.subtitle==="string"&&heading.subtitle.length<=2000){let subtitle=identity.querySelector("p");if(!subtitle){subtitle=projectedSubtitle=h("p");identity.appendChild(subtitle)}
163
170
  subtitle.classList.add("cx-record-subtitle");setText(subtitle,heading.subtitle);subtitle.hidden=!heading.subtitle}}catch(error){view.emit("error",{error})}});recordActionsMenu(view,dialog,identity);dialog.addEventListener("keydown",event=>{if(event.altKey&&event.key==="ArrowLeft"&&state.stack.length){event.preventDefault();recordBack(view,dialog)}});dialog.addEventListener("close",()=>{if(view.destroyed)return;const owner=view._recordLinkOwner;if(owner?.dialog!==dialog)return;if(dialog._replaced){view._recordLinkOwner=null;return}