plass-ui 1.4.0 → 1.6.0

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 (268) hide show
  1. package/CHANGELOG.md +432 -0
  2. package/README.md +45 -23
  3. package/dist/components/accordion/PlAccordion.d.ts +1 -1
  4. package/dist/components/alert/PlAlert.js +1 -1
  5. package/dist/components/anchor/PlAnchor.d.ts +14 -1
  6. package/dist/components/anchor/PlAnchor.js +1 -1
  7. package/dist/components/animate-appear/PlAnimateAppear.js +1 -1
  8. package/dist/components/animate-blink/PlAnimateBlink.js +1 -1
  9. package/dist/components/animate-counter/PlAnimateCounter.js +1 -1
  10. package/dist/components/animate-fade/PlAnimateFade.js +1 -1
  11. package/dist/components/animate-float/PlAnimateFloat.js +1 -1
  12. package/dist/components/animate-grow/PlAnimateGrow.js +1 -1
  13. package/dist/components/animate-headline/PlAnimateHeadline.js +1 -1
  14. package/dist/components/animate-lighting/PlAnimateLighting.js +1 -1
  15. package/dist/components/animate-marquee/PlAnimateMarquee.d.ts +16 -4
  16. package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -1
  17. package/dist/components/animate-reveal/PlAnimateReveal.js +1 -1
  18. package/dist/components/animate-rotate/PlAnimateRotate.js +1 -1
  19. package/dist/components/animate-scramble/PlAnimateScramble.js +1 -1
  20. package/dist/components/animate-shake/PlAnimateShake.js +1 -1
  21. package/dist/components/animate-slide/PlAnimateSlide.js +1 -1
  22. package/dist/components/animate-split/PlAnimateSplit.d.ts +7 -4
  23. package/dist/components/animate-split/PlAnimateSplit.js +1 -1
  24. package/dist/components/animate-typing/PlAnimateTyping.d.ts +3 -2
  25. package/dist/components/animate-typing/PlAnimateTyping.js +1 -1
  26. package/dist/components/animate-zoom/PlAnimateZoom.js +1 -1
  27. package/dist/components/app-logo/PlAppLogo.js +1 -1
  28. package/dist/components/area-chart/PlAreaChart.d.ts +1 -1
  29. package/dist/components/area-chart/PlAreaChart.js +1 -1
  30. package/dist/components/aspect-ratio/PlAspectRatio.d.ts +2 -1
  31. package/dist/components/aspect-ratio/PlAspectRatio.js +1 -1
  32. package/dist/components/avatar/PlAvatar.js +1 -1
  33. package/dist/components/back-top/PlBackTop.d.ts +8 -1
  34. package/dist/components/back-top/PlBackTop.js +1 -1
  35. package/dist/components/badge/PlBadge.js +1 -1
  36. package/dist/components/bar-chart/PlBarChart.d.ts +1 -1
  37. package/dist/components/bar-chart/PlBarChart.js +1 -1
  38. package/dist/components/blockquote/PlBlockquote.js +1 -1
  39. package/dist/components/bottom-navigation/PlBottomNavigation.d.ts +3 -0
  40. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
  41. package/dist/components/button/PlButton.d.ts +8 -0
  42. package/dist/components/button/PlButton.js +1 -1
  43. package/dist/components/calendar/PlCalendar.js +1 -1
  44. package/dist/components/card/PlCard.js +1 -1
  45. package/dist/components/carousel/PlCarousel.d.ts +1 -1
  46. package/dist/components/carousel/PlCarousel.js +1 -1
  47. package/dist/components/chat-bubble/PlChatBubble.d.ts +4 -1
  48. package/dist/components/chat-bubble/PlChatBubble.js +1 -1
  49. package/dist/components/checkbox/PlCheckbox.js +1 -1
  50. package/dist/components/chip/PlChip.d.ts +6 -2
  51. package/dist/components/chip/PlChip.js +1 -1
  52. package/dist/components/code-block/PlCodeBlock.d.ts +19 -2
  53. package/dist/components/code-block/PlCodeBlock.js +1 -1
  54. package/dist/components/color-picker/PlColorPicker.d.ts +19 -2
  55. package/dist/components/color-picker/PlColorPicker.js +1 -1
  56. package/dist/components/combobox/PlCombobox.d.ts +14 -7
  57. package/dist/components/combobox/PlCombobox.js +1 -1
  58. package/dist/components/command-palette/PlCommandPalette.d.ts +6 -2
  59. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  60. package/dist/components/confirm/PlConfirmProvider.js +1 -1
  61. package/dist/components/container/PlContainer.js +1 -1
  62. package/dist/components/data-table/PlDataTable.d.ts +20 -6
  63. package/dist/components/data-table/PlDataTable.js +1 -1
  64. package/dist/components/date-picker/PlDatePicker.js +1 -1
  65. package/dist/components/date-range-picker/PlDateRangePicker.js +1 -1
  66. package/dist/components/date-time-picker/PlDateTimePicker.js +1 -1
  67. package/dist/components/drawer/PlDrawer.js +1 -1
  68. package/dist/components/empty/PlEmpty.js +1 -1
  69. package/dist/components/file-picker/PlFilePicker.d.ts +22 -3
  70. package/dist/components/file-picker/PlFilePicker.js +1 -1
  71. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.d.ts +3 -0
  72. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
  73. package/dist/components/form/PlForm.js +1 -1
  74. package/dist/components/gallery/PlGallery.d.ts +40 -2
  75. package/dist/components/gallery/PlGallery.js +1 -1
  76. package/dist/components/gallery/PlGalleryViewer.js +1 -1
  77. package/dist/components/gauge-chart/PlGaugeChart.js +1 -1
  78. package/dist/components/heatmap-chart/PlHeatmapChart.js +1 -1
  79. package/dist/components/highlight/PlHighlight.d.ts +10 -3
  80. package/dist/components/highlight/PlHighlight.js +1 -1
  81. package/dist/components/hot-keys/PlHotKeys.js +1 -1
  82. package/dist/components/hover-card/PlHoverCard.d.ts +5 -3
  83. package/dist/components/hover-card/PlHoverCard.js +1 -1
  84. package/dist/components/how-to-steps/PlHowToSteps.js +1 -1
  85. package/dist/components/image/PlImage.d.ts +195 -8
  86. package/dist/components/image/PlImage.js +1 -1
  87. package/dist/components/image/PlImagePreview.d.ts +58 -0
  88. package/dist/components/image/PlImagePreview.js +1 -0
  89. package/dist/components/image/index.d.ts +1 -1
  90. package/dist/components/list/PlList.js +1 -1
  91. package/dist/components/menu/PlMenu.d.ts +14 -5
  92. package/dist/components/menu/PlMenu.js +1 -1
  93. package/dist/components/meter/PlMeter.js +1 -1
  94. package/dist/components/navigation-menu/PlNavigationMenu.d.ts +7 -1
  95. package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
  96. package/dist/components/number-field/PlNumberField.d.ts +12 -4
  97. package/dist/components/number-field/PlNumberField.js +1 -1
  98. package/dist/components/otp-field/PlOtpField.d.ts +15 -1
  99. package/dist/components/otp-field/PlOtpField.js +1 -1
  100. package/dist/components/page-layout/PlPageLayout.js +1 -1
  101. package/dist/components/pagination/PlPagination.d.ts +12 -9
  102. package/dist/components/pagination/PlPagination.js +1 -1
  103. package/dist/components/panes/PlPanes.d.ts +5 -0
  104. package/dist/components/panes/PlPanes.js +1 -1
  105. package/dist/components/pie-chart/PlPieChart.js +1 -1
  106. package/dist/components/pill/PlPill.js +1 -1
  107. package/dist/components/popover/PlPopover.d.ts +5 -5
  108. package/dist/components/popover/PlPopover.js +1 -1
  109. package/dist/components/progress-box/PlProgressBox.js +1 -1
  110. package/dist/components/progress-circular/PlProgressCircular.js +1 -1
  111. package/dist/components/progress-linear/PlProgressLinear.js +1 -1
  112. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  113. package/dist/components/rating/PlRating.d.ts +1 -1
  114. package/dist/components/rating/PlRating.js +1 -1
  115. package/dist/components/scatter-chart/PlScatterChart.js +1 -1
  116. package/dist/components/scroll-area/PlScrollArea.js +1 -1
  117. package/dist/components/scroll-zone/PlScrollZone.d.ts +19 -6
  118. package/dist/components/scroll-zone/PlScrollZone.js +1 -1
  119. package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
  120. package/dist/components/select/PlSelect.d.ts +8 -2
  121. package/dist/components/select/PlSelect.js +1 -1
  122. package/dist/components/show/PlShow.d.ts +16 -0
  123. package/dist/components/show/PlShow.js +1 -1
  124. package/dist/components/sidebar/PlSidebar.js +1 -1
  125. package/dist/components/sidebar/PlSidebarTrigger.js +1 -1
  126. package/dist/components/skeleton/PlSkeleton.js +1 -1
  127. package/dist/components/slider/PlSlider.d.ts +13 -1
  128. package/dist/components/slider/PlSlider.js +1 -1
  129. package/dist/components/sparkline/PlSparkline.js +1 -1
  130. package/dist/components/spoiler/PlSpoiler.d.ts +15 -8
  131. package/dist/components/spoiler/PlSpoiler.js +1 -1
  132. package/dist/components/stat/PlStat.d.ts +4 -0
  133. package/dist/components/stat/PlStat.js +1 -1
  134. package/dist/components/stepper/PlStepper.d.ts +1 -1
  135. package/dist/components/stepper/PlStepper.js +1 -1
  136. package/dist/components/switch/PlSwitch.js +1 -1
  137. package/dist/components/table/PlTable.d.ts +5 -5
  138. package/dist/components/tabs/PlTabs.d.ts +26 -1
  139. package/dist/components/tabs/PlTabs.js +1 -1
  140. package/dist/components/text-field/PlTextField.d.ts +15 -5
  141. package/dist/components/text-field/PlTextField.js +1 -1
  142. package/dist/components/text-link/PlTextLink.js +1 -1
  143. package/dist/components/time-picker/PlTimePicker.js +1 -1
  144. package/dist/components/timeline/PlTimeline.js +1 -1
  145. package/dist/components/timeline-chart/PlTimelineChart.js +1 -1
  146. package/dist/components/toast/PlToast.js +1 -1
  147. package/dist/components/toggle/PlToggle.js +1 -1
  148. package/dist/components/tooltip/PlTooltip.js +1 -1
  149. package/dist/components/tour/PlTour.js +1 -1
  150. package/dist/components/transfer/PlTransfer.d.ts +10 -1
  151. package/dist/components/transfer/PlTransfer.js +1 -1
  152. package/dist/components/tree/PlTree.js +1 -1
  153. package/dist/components/tree-select/PlTreeSelect.js +1 -1
  154. package/dist/components/typography/PlTypography.js +1 -1
  155. package/dist/components/window-pane/PlWindowPane.d.ts +3 -3
  156. package/dist/components/window-pane/PlWindowPane.js +1 -1
  157. package/dist/css/area-chart.css +1 -0
  158. package/dist/css/back-top.css +2 -0
  159. package/dist/css/bar-chart.css +1 -0
  160. package/dist/css/calendar.css +1 -0
  161. package/dist/css/carousel.css +2 -0
  162. package/dist/css/color-picker.css +1 -0
  163. package/dist/css/combobox.css +1 -0
  164. package/dist/css/command-palette.css +1 -0
  165. package/dist/css/confirm.css +2 -0
  166. package/dist/css/data-table.css +5 -0
  167. package/dist/css/date-picker.css +1 -0
  168. package/dist/css/date-range-picker.css +1 -0
  169. package/dist/css/date-time-picker.css +1 -0
  170. package/dist/css/floating-action-button.css +2 -0
  171. package/dist/css/gallery.css +5 -0
  172. package/dist/css/gauge-chart.css +1 -0
  173. package/dist/css/heatmap-chart.css +1 -0
  174. package/dist/css/icon-button.css +1 -0
  175. package/dist/css/image.css +2 -0
  176. package/dist/css/line-chart.css +1 -0
  177. package/dist/css/menubar.css +1 -0
  178. package/dist/css/pagination.css +1 -0
  179. package/dist/css/pie-chart.css +1 -0
  180. package/dist/css/popconfirm.css +2 -0
  181. package/dist/css/scatter-chart.css +1 -0
  182. package/dist/css/scroll-zone.css +2 -0
  183. package/dist/css/sidebar.css +3 -0
  184. package/dist/css/sparkline.css +1 -0
  185. package/dist/css/spoiler.css +1 -0
  186. package/dist/css/stat.css +1 -0
  187. package/dist/css/time-picker.css +1 -0
  188. package/dist/css/timeline-chart.css +1 -0
  189. package/dist/css/tour.css +1 -0
  190. package/dist/css/transfer.css +4 -0
  191. package/dist/css/tree-select.css +2 -0
  192. package/dist/hooks/usePlElementSize.d.ts +4 -1
  193. package/dist/hooks/usePlElementSize.js +1 -1
  194. package/dist/hooks/usePlHotKeys.d.ts +5 -1
  195. package/dist/hooks/usePlHotKeys.js +1 -1
  196. package/dist/hooks/usePlOnScreen.d.ts +4 -0
  197. package/dist/hooks/usePlOnScreen.js +1 -1
  198. package/dist/internal/animate.d.ts +24 -21
  199. package/dist/internal/animate.js +1 -1
  200. package/dist/internal/calendar.js +1 -1
  201. package/dist/internal/chart-frame.d.ts +3 -14
  202. package/dist/internal/chart-frame.js +1 -1
  203. package/dist/internal/chart-line.js +1 -1
  204. package/dist/internal/chart.d.ts +90 -3
  205. package/dist/internal/chart.js +1 -1
  206. package/dist/internal/color-scheme.js +1 -1
  207. package/dist/internal/data-table.d.ts +5 -4
  208. package/dist/internal/data-table.js +1 -1
  209. package/dist/internal/date.d.ts +10 -0
  210. package/dist/internal/date.js +1 -1
  211. package/dist/internal/defaults.d.ts +14 -1
  212. package/dist/internal/drag.d.ts +16 -0
  213. package/dist/internal/drag.js +1 -1
  214. package/dist/internal/focusable.d.ts +8 -0
  215. package/dist/internal/focusable.js +1 -0
  216. package/dist/internal/form.d.ts +61 -0
  217. package/dist/internal/form.js +1 -0
  218. package/dist/internal/gallery.d.ts +60 -14
  219. package/dist/internal/gallery.js +1 -1
  220. package/dist/internal/glow.d.ts +32 -0
  221. package/dist/internal/glow.js +1 -0
  222. package/dist/internal/highlight.js +1 -1
  223. package/dist/internal/image.d.ts +94 -0
  224. package/dist/internal/image.js +1 -0
  225. package/dist/internal/inert.d.ts +19 -0
  226. package/dist/internal/inert.js +1 -0
  227. package/dist/internal/keys.d.ts +19 -0
  228. package/dist/internal/keys.js +1 -1
  229. package/dist/internal/labels.d.ts +58 -1
  230. package/dist/internal/labels.js +1 -1
  231. package/dist/internal/link.d.ts +17 -0
  232. package/dist/internal/link.js +1 -1
  233. package/dist/internal/notch.d.ts +83 -0
  234. package/dist/internal/notch.js +1 -0
  235. package/dist/internal/page-layout.d.ts +14 -7
  236. package/dist/internal/page-layout.js +1 -1
  237. package/dist/internal/picker.d.ts +51 -8
  238. package/dist/internal/picker.js +1 -1
  239. package/dist/internal/progress.d.ts +16 -8
  240. package/dist/internal/progress.js +1 -1
  241. package/dist/internal/scramble.d.ts +4 -0
  242. package/dist/internal/scramble.js +1 -1
  243. package/dist/internal/scroll-target.d.ts +5 -0
  244. package/dist/internal/scroll-target.js +1 -0
  245. package/dist/internal/steps.js +1 -1
  246. package/dist/internal/styles.d.ts +87 -0
  247. package/dist/internal/styles.js +1 -1
  248. package/dist/internal/text.d.ts +39 -0
  249. package/dist/internal/text.js +1 -0
  250. package/dist/internal/watermark.d.ts +44 -0
  251. package/dist/internal/watermark.js +1 -0
  252. package/dist/internal/wheel.d.ts +52 -0
  253. package/dist/internal/wheel.js +1 -0
  254. package/dist/internal/window.js +1 -1
  255. package/dist/locales/de.js +1 -1
  256. package/dist/locales/es.js +1 -1
  257. package/dist/locales/fr.js +1 -1
  258. package/dist/locales/ja.js +1 -1
  259. package/dist/locales/ko.js +1 -1
  260. package/dist/locales/zh-Hans.js +1 -1
  261. package/dist/provider/PlColorSchemeScript.js +1 -1
  262. package/dist/provider/PlassProvider.d.ts +4 -3
  263. package/dist/provider/PlassProvider.js +1 -1
  264. package/dist/styles.css +1 -1
  265. package/dist/tailwind.css +313 -15
  266. package/dist/tokens.css +313 -15
  267. package/dist/types.d.ts +71 -29
  268. package/package.json +15 -15
@@ -1 +1 @@
1
- import{dateFormatter as t,numberFormatter as e}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--plass-chart-1)","var(--plass-chart-2)","var(--plass-chart-3)","var(--plass-chart-4)","var(--plass-chart-5)","var(--plass-chart-6)","var(--plass-chart-7)","var(--plass-chart-8)"];const n=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return n.has(t)?`var(--plass-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoryExtent(t,e){let n=1/0,r=-1/0,o=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(o=!0,n=Math.min(n,i),r=Math.max(r,i))})}),o?{min:n,max:r}:null}export function bubbleRadius(t,e,n,r){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(r,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:r}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,r=-1/0,o=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(o=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),r=Math.max(r,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(o=!0,n=Math.min(n,t),r=Math.max(r,t));return o?{min:n,max:r}:null}function niceStep(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5,includeZero:r=!0}=e;let o=e.min??(t?t.min:0),a=e.max??(t?t.max:1);if(r&&void 0===e.min&&(o=Math.min(o,0)),r&&void 0===e.max&&(a=Math.max(a,0)),a===o){const t=Math.abs(a)>0?.5*Math.abs(a):1;o-=t,a+=t}const i=void 0!==e.min&&void 0!==e.max?function dividingStep(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let r=niceStep(t/Math.max(1,e)),o=1/0;for(const a of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*a*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const l=Math.abs(c-e);l<o&&(o=l,r=u)}return r}(a-o,n):niceStep((a-o)/Math.max(1,n)),u=void 0!==e.min?o:Math.floor(o/i)*i,s=void 0!==e.max?a:Math.ceil(a/i)*i,c=s-u||1,l=[];for(let t=u;t<=s+1e-9*i;t+=i)l.push(Number(t.toFixed(12)));return{min:u,max:s,ticks:l,fraction:t=>(t-u)/c}}const r=1e3,o=6e4,a=36e5,i=24*a,u=[{unit:"second",count:1,size:r},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:o},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:a},{unit:"hour",count:3,size:3*a},{unit:"hour",count:6,size:6*a},{unit:"hour",count:12,size:12*a},{unit:"day",count:1,size:i},{unit:"day",count:2,size:2*i},{unit:"week",count:1,size:7*i},{unit:"week",count:2,size:14*i},{unit:"month",count:1,size:30*i},{unit:"quarter",count:1,size:91*i},{unit:"month",count:6,size:182*i},{unit:"year",count:1,size:365*i}];function addTime(t,e,n){const a=new Date(t);if("year"===e)a.setFullYear(a.getFullYear()+n);else if("quarter"===e)a.setMonth(a.getMonth()+3*n);else if("month"===e)a.setMonth(a.getMonth()+n);else if("week"===e)a.setDate(a.getDate()+7*n);else if("day"===e)a.setDate(a.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?o:r);a.setHours(a.getHours()+n)}return a.getTime()}const s={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};export function timeScale(t,e={}){const{tickCount:n=6}=e;let a=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),c=e.max??t?.max??a+i;c<=a&&(a-=i/2,c+=i/2);const l=c-a;let h=u[0],m=1/0;for(const t of u){const e=Math.abs(l/t.size-n);e<m&&(m=e,h=t)}const $=h.unit,f="year"===$?Math.max(1,Math.round(niceStep(l/n/(365*i)))):h.count,x=e.min??function alignTime(t,e,n){let a=function floorTime(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/o)*o:Math.floor(t/r)*r}(t,s[e]);if("year"===e&&n>1){const t=new Date(a).getFullYear();a=new Date(t-(t%n+n)%n,0,1).getTime()}for(let r=0;r<500;r++){const r=addTime(a,e,n);if(r>t)return a;a=r}return a}(a,$,f),p=[];let M=x;for(let t=0;t<500&&(p.push(M),!(M>c));t++)M=addTime(M,$,f);const g=e.max??p[p.length-1],d=g-x||1;return{min:x,max:g,ticks:p.filter(t=>t>=x&&t<=g),unit:$,step:f,fraction:t=>(t-x)/d}}function timeParts(t,e){if("second"===t)return{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"};if("minute"===t||"hour"===t)return{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if("year"===t)return{year:"numeric"};const n="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...n,year:"numeric"}:n}export function formatTimeValue(e,n,r){return t(r,timeParts(n,!0)).format(new Date(e))}export function formatTimeTicks(e,n,r){const o=new Set(e.map(t=>new Date(t).getFullYear())).size>1;return e.map((e,a)=>t(r,timeParts(n,o||0===a)).format(new Date(e)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const r=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/r))}export function showsTick(t,e,n,r){return t%n===0||r&&t===e-1}export function fitsLast(t,e,n,r){const o=(t-1)%e;return o>0&&o*n>=r+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const r=e-textWidth("…",n);let o="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>r)break;a=t,o+=e}return o.length>0?`${o.trimEnd()}…`:"…"}export function bandScale(t,e,n){const r=t>0?e/t:e;return{step:r,band:r*n,centre:t=>r*(t+.5)}}export function linePath(t,e){const n=[];let r=[];const flush=()=>{if(0!==r.length){if(1===r.length)n.push(`M${r[0].x} ${r[0].y}h0`);else if("step"===e){n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++){const e=(r[t-1].x+r[t].x)/2;n.push(`H${e}V${r[t].y}H${r[t].x}`)}}else if("smooth"===e)n.push(`M${r[0].x} ${r[0].y}`),n.push(function monotonePath(t){const e=t.length,n=[];for(let r=0;r<e-1;r++){const e=t[r+1].x-t[r].x;n.push(0===e?0:(t[r+1].y-t[r].y)/e)}const r=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],o=n[t];r.push(e*o<=0?0:2*e*o/(e+o))}r.push(n[e-2]??0);const o=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;o.push(`C${t[n].x+e} ${t[n].y+r[n]*e} ${t[n+1].x-e} ${t[n+1].y-r[n+1]*e} ${t[n+1].x} ${t[n+1].y}`)}return o.join("")}(r));else{n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++)n.push(`L${r[t].x} ${r[t].y}`)}r=[]}};for(const e of t)null===e?flush():r.push(e);return flush(),n.join("")}export function areaPath(t,e,n){const r=[];let o=0;const flush=a=>{const i=t.slice(o,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(o,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");r.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(flush(e),o=e+1);return flush(t.length),r.join("")}export function barPath(t,e,n,r,o,a){const i=Math.max(0,Math.min(o,n/2,r/2));if(0===i||n<=0||r<=0)return`M${t} ${e}h${n}v${r}h${-n}Z`;const arc=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`;return"up"===a?`M${t} ${e+r}V${e+i}${arc(i,-i)}H${t+n-i}${arc(i,i)}V${e+r}Z`:"down"===a?`M${t} ${e}H${t+n}V${e+r-i}${arc(-i,i)}H${t+i}${arc(-i,-i)}Z`:"right"===a?`M${t} ${e}H${t+n-i}${arc(i,i)}V${e+r-i}${arc(-i,i)}H${t}Z`:`M${t+n} ${e+r}H${t+i}${arc(-i,-i)}V${e+i}${arc(i,-i)}H${t+n}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const c={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,r){const o=Math.max(0,r)*c[t];if(0===o)return"";if("circle"===t)return`M${e-o} ${n}a${o} ${o} 0 1 0 ${2*o} 0a${o} ${o} 0 1 0 ${2*-o} 0Z`;if("square"===t)return`M${e-o} ${n-o}h${2*o}v${2*o}h${2*-o}Z`;if("diamond"===t)return`M${e} ${n-o}L${e+o} ${n}L${e} ${n+o}L${e-o} ${n}Z`;if("triangle"===t)return`M${[0,120,240].map(t=>{const r=(t-90)*Math.PI/180;return`${e+o*Math.cos(r)} ${n+o*Math.sin(r)}`}).join("L")}Z`;const a=o/3;return`M${e-a} ${n-o}h${2*a}v${o-a}h${o-a}v${2*a}h${-(o-a)}v${o-a}h${2*-a}v${-(o-a)}h${-(o-a)}v${2*-a}h${o-a}Z`}export function ringPath(t,e,n,r,o){const point=r=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(o-r)>=360){const t=r+180;return`M${point(r)}A${n} ${n} 0 1 1 ${point(t)}A${n} ${n} 0 1 1 ${point(r)}`}const a=Math.abs(o-r)>180?1:0;return`M${point(r)}A${n} ${n} 0 ${a} 1 ${point(o)}`}export function arcPath(t,e,n,r,o,a){const point=(n,r)=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(a-o)>=360){const t=o+180;return r>0?`M${point(n,o)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,o)}ZM${point(r,o)}A${r} ${r} 0 1 0 ${point(r,t)}A${r} ${r} 0 1 0 ${point(r,o)}Z`:`M${point(n,o)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,o)}Z`}const i=Math.abs(a-o)>180?1:0;return r<=0?`M${t} ${e}L${point(n,o)}A${n} ${n} 0 ${i} 1 ${point(n,a)}Z`:`M${point(n,o)}A${n} ${n} 0 ${i} 1 ${point(n,a)}L${point(r,a)}A${r} ${r} 0 ${i} 0 ${point(r,o)}Z`}export const rampSteps=5;export function rampStep(t,e,n,r,o=0){if("diverging"===r){const r=Math.max(Math.abs(n-o),Math.abs(o-e));if(!(r>0))return 2;const a=(t-o)/r;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):4}export function rampFill(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const r=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(r>0)||e<=0||n<=0)return[];const o=e*n/r,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*o})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,l=n,h=[];const worst=t=>{const e=Math.min(c,l),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const r=t[0].area,o=t[t.length-1].area;return Math.max(e*e*r/(n*n),n*n/(e*e*o))},place=()=>{const t=h.reduce((t,e)=>t+e.area,0),e=Math.min(c,l),n=e>0?t/e:0,r=c>=l;let o=0;for(const t of h){const e=n>0?t.area/n:0;i.push(r?{index:t.index,x:u,y:s+o,width:n,height:e}:{index:t.index,x:u+o,y:s,width:e,height:n}),o+=e}r?(u+=n,c-=n):(s+=n,l-=n),h=[]};for(const t of a)0===h.length||worst([...h,t])<=worst(h)||place(),h.push(t);return h.length>0&&place(),i}const l={month:"short",day:"numeric"},h={notation:"compact",maximumFractionDigits:1},m={maximumFractionDigits:2};export function formatCategory(e,n){return e instanceof Date?t(n,l).format(e):String(e)}export function compactNumber(t,n){return Math.abs(t)>=1e4?e(n,h).format(t):e(n,m).format(t)}
1
+ import{dateFormatter as t,numberFormatter as e}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const lineDash="6 4";export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--plass-chart-1)","var(--plass-chart-2)","var(--plass-chart-3)","var(--plass-chart-4)","var(--plass-chart-5)","var(--plass-chart-6)","var(--plass-chart-7)","var(--plass-chart-8)"];const n=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return n.has(t)?`var(--plass-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}export function dimmedByHover(t,e,n){return null!==t&&t!==e&&!0===n[t]}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function labelledPoints(t,e){if("none"===e)return()=>!1;if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let n=t.length-1;n>=0;n--)if(null!==t[n].value){e=n;break}return t=>t===e}let n=1/0,r=-1/0;for(const e of t)null!==e.value&&(n=Math.min(n,e.value),r=Math.max(r,e.value));return e=>{const o=t[e].value;return null!==o&&(o===n||o===r)}}export function stackToFull(t,e){const n=toValues(t),r=[];for(const t of n)t.forEach((t,e)=>{r[e]=(r[e]??0)+Math.abs(t.value??0)});return t.map((t,o)=>({...t,data:n[o].map((t,n)=>{if(null===t.value)return null;const o=r[n];return{x:t.x,y:0===o?0:t.value/o*100,color:t.color,label:t.label??e(t.value)}})}))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoriesAreDates(t,e){return(e?.some(t=>t instanceof Date)??!1)||t.some(t=>t.some(t=>t.x instanceof Date))}export function categoryExtent(t,e){let n=1/0,r=-1/0,o=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(o=!0,n=Math.min(n,i),r=Math.max(r,i))})}),o?{min:n,max:r}:null}export function bubbleRadius(t,e,n,r){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(r,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:r}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,r=-1/0,o=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(o=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),r=Math.max(r,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(o=!0,n=Math.min(n,t),r=Math.max(r,t));return o?{min:n,max:r}:null}function niceStep(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5,includeZero:r=!0}=e;let o=e.min??(t?t.min:0),a=e.max??(t?t.max:1);if(r&&void 0===e.min&&(o=Math.min(o,0)),r&&void 0===e.max&&(a=Math.max(a,0)),a===o){const t=Math.abs(a)>0?.5*Math.abs(a):1,n=void 0===e.min,r=void 0===e.max;!n&&r||(o-=t),!r&&n||(a+=t)}const i=void 0!==e.min&&void 0!==e.max?function dividingStep(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let r=niceStep(t/Math.max(1,e)),o=1/0;for(const a of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*a*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const l=Math.abs(c-e);l<o&&(o=l,r=u)}return r}(a-o,n):niceStep((a-o)/Math.max(1,n)),u=void 0!==e.min?o:Math.floor(o/i)*i,s=void 0!==e.max?a:Math.ceil(a/i)*i,c=s-u||1,l=[];for(let t=u;t<=s+1e-9*i;t+=i)l.push(Number(t.toFixed(12)));return{min:u,max:s,ticks:l,fraction:t=>(t-u)/c}}const r=1e3,o=6e4,a=36e5,i=24*a,u=[{unit:"second",count:1,size:r},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:o},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:a},{unit:"hour",count:3,size:3*a},{unit:"hour",count:6,size:6*a},{unit:"hour",count:12,size:12*a},{unit:"day",count:1,size:i},{unit:"day",count:2,size:2*i},{unit:"week",count:1,size:7*i},{unit:"week",count:2,size:14*i},{unit:"month",count:1,size:30*i},{unit:"quarter",count:1,size:91*i},{unit:"month",count:6,size:182*i},{unit:"year",count:1,size:365*i}];function floorTime(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/o)*o:Math.floor(t/r)*r}function addTime(t,e,n){const a=new Date(t);if("year"===e)a.setFullYear(a.getFullYear()+n);else if("quarter"===e)a.setMonth(a.getMonth()+3*n);else if("month"===e)a.setMonth(a.getMonth()+n);else if("week"===e)a.setDate(a.getDate()+7*n);else if("day"===e)a.setDate(a.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?o:r);a.setHours(a.getHours()+n)}return a.getTime()}const s={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};export function timeScale(t,e={}){const{tickCount:n=6}=e;let r=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),o=e.max??t?.max??r+i;o<=r&&(r-=i/2,o+=i/2);const a=o-r;let c=u[0],l=1/0;for(const t of u){const e=Math.abs(a/t.size-n);e<l&&(l=e,c=t)}const h=c.unit,m="year"===h?Math.max(1,Math.round(niceStep(a/n/(365*i)))):c.count;let f=e.min??function alignTime(t,e,n){let r=floorTime(t,s[e]);if("year"===e&&n>1){const t=new Date(r).getFullYear();r=new Date(t-(t%n+n)%n,0,1).getTime()}for(let o=0;o<500;o++){const o=addTime(r,e,n);if(o>t)return r;r=o}return r}(r,h,m);const $=[];let x=f;for(let t=0;t<500&&($.push(x),!(x>o));t++)x=addTime(x,h,m);let p=e.max??$[$.length-1];p<=f&&(f-=i/2,p+=i/2);const M=p-f;return{min:f,max:p,ticks:$.filter(t=>t>=f&&t<=p),unit:h,step:m,fraction:t=>(t-f)/M}}function timeParts(t,e,n=!1){if("second"===t||"minute"===t||"hour"===t){const r="second"===t?{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"}:{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if(!n)return r;const o={month:"short",day:"numeric",...r};return e?{...o,year:"numeric"}:o}if("year"===t)return{year:"numeric"};const r="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...r,year:"numeric"}:r}export function timeNeedsDate(t,e){return!("second"!==e&&"minute"!==e&&"hour"!==e||t.length<2||floorTime(t[0],"day")===floorTime(t[t.length-1]-1,"day"))}export function formatTimeValue(e,n,r,o=!1){return t(r,timeParts(n,!0,o)).format(new Date(e))}export function formatTimeTicks(e,n,r){const o=new Set(e.map(t=>new Date(t).getFullYear())).size>1,a=timeNeedsDate(e,n);return e.map((e,i)=>t(r,timeParts(n,o||0===i,a)).format(new Date(e)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const r=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/r))}export function showsTick(t,e,n,r){return t%n===0||r&&t===e-1}export function fitsLast(t,e,n,r){const o=(t-1)%e;return o>0&&o*n>=r+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const r=e-textWidth("…",n);let o="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>r)break;a=t,o+=e}return o.length>0?`${o.trimEnd()}…`:"…"}export function fitCategoryLabels(t,e){const{horizontal:n,slot:r,fontSize:o,ticks:a}=e;return a||!n&&r-6<2.4*o?t:t.map(t=>truncate(t,n?150:r-6,o))}export function bandScale(t,e,n){const r=t>0?e/t:e;return{step:r,band:r*n,centre:t=>r*(t+.5)}}export function linePath(t,e){const n=[];let r=[];const flush=()=>{if(0!==r.length){if(1===r.length)n.push(`M${r[0].x} ${r[0].y}h0`);else if("step"===e){n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++){const e=(r[t-1].x+r[t].x)/2;n.push(`H${e}V${r[t].y}H${r[t].x}`)}}else if("smooth"===e)n.push(`M${r[0].x} ${r[0].y}`),n.push(function monotonePath(t){const e=t.length,n=[];for(let r=0;r<e-1;r++){const e=t[r+1].x-t[r].x;n.push(0===e?0:(t[r+1].y-t[r].y)/e)}const r=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],o=n[t];r.push(e*o<=0?0:2*e*o/(e+o))}r.push(n[e-2]??0);const o=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;o.push(`C${t[n].x+e} ${t[n].y+r[n]*e} ${t[n+1].x-e} ${t[n+1].y-r[n+1]*e} ${t[n+1].x} ${t[n+1].y}`)}return o.join("")}(r));else{n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++)n.push(`L${r[t].x} ${r[t].y}`)}r=[]}};for(const e of t)null===e?flush():r.push(e);return flush(),n.join("")}export function areaPath(t,e,n){const r=[];let o=0;const flush=a=>{const i=t.slice(o,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(o,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");r.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(flush(e),o=e+1);return flush(t.length),r.join("")}export function barPath(t,e,n,r,o,a){const i=Math.max(0,Math.min(o,n/2,r/2));if(0===i||n<=0||r<=0)return`M${t} ${e}h${n}v${r}h${-n}Z`;const arc=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`;return"up"===a?`M${t} ${e+r}V${e+i}${arc(i,-i)}H${t+n-i}${arc(i,i)}V${e+r}Z`:"down"===a?`M${t} ${e}H${t+n}V${e+r-i}${arc(-i,i)}H${t+i}${arc(-i,-i)}Z`:"right"===a?`M${t} ${e}H${t+n-i}${arc(i,i)}V${e+r-i}${arc(-i,i)}H${t}Z`:`M${t+n} ${e+r}H${t+i}${arc(-i,-i)}V${e+i}${arc(i,-i)}H${t+n}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const c={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,r){const o=Math.max(0,r)*c[t];if(0===o)return"";if("circle"===t)return`M${e-o} ${n}a${o} ${o} 0 1 0 ${2*o} 0a${o} ${o} 0 1 0 ${2*-o} 0Z`;if("square"===t)return`M${e-o} ${n-o}h${2*o}v${2*o}h${2*-o}Z`;if("diamond"===t)return`M${e} ${n-o}L${e+o} ${n}L${e} ${n+o}L${e-o} ${n}Z`;if("triangle"===t)return`M${[0,120,240].map(t=>{const r=(t-90)*Math.PI/180;return`${e+o*Math.cos(r)} ${n+o*Math.sin(r)}`}).join("L")}Z`;const a=o/3;return`M${e-a} ${n-o}h${2*a}v${o-a}h${o-a}v${2*a}h${-(o-a)}v${o-a}h${2*-a}v${-(o-a)}h${-(o-a)}v${2*-a}h${o-a}Z`}export function ringPath(t,e,n,r,o){const point=r=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(o-r)>=360){const t=r+180;return`M${point(r)}A${n} ${n} 0 1 1 ${point(t)}A${n} ${n} 0 1 1 ${point(r)}`}const a=Math.abs(o-r)>180?1:0;return`M${point(r)}A${n} ${n} 0 ${a} 1 ${point(o)}`}export function arcPath(t,e,n,r,o,a){const point=(n,r)=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(a-o)>=360){const t=o+180;return r>0?`M${point(n,o)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,o)}ZM${point(r,o)}A${r} ${r} 0 1 0 ${point(r,t)}A${r} ${r} 0 1 0 ${point(r,o)}Z`:`M${point(n,o)}A${n} ${n} 0 1 1 ${point(n,t)}A${n} ${n} 0 1 1 ${point(n,o)}Z`}const i=Math.abs(a-o)>180?1:0;return r<=0?`M${t} ${e}L${point(n,o)}A${n} ${n} 0 ${i} 1 ${point(n,a)}Z`:`M${point(n,o)}A${n} ${n} 0 ${i} 1 ${point(n,a)}L${point(r,a)}A${r} ${r} 0 ${i} 0 ${point(r,o)}Z`}export const rampSteps=5;export function rampStep(t,e,n,r,o=0){if("diverging"===r){const r=Math.max(Math.abs(n-o),Math.abs(o-e));if(!(r>0))return 2;const a=(t-o)/r;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):4}export function rampFill(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--plass-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const r=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(r>0)||e<=0||n<=0)return[];const o=e*n/r,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*o})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,l=n,h=[];const worst=t=>{const e=Math.min(c,l),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const r=t[0].area,o=t[t.length-1].area;return Math.max(e*e*r/(n*n),n*n/(e*e*o))},place=()=>{const t=h.reduce((t,e)=>t+e.area,0),e=Math.min(c,l),n=e>0?t/e:0,r=c>=l;let o=0;for(const t of h){const e=n>0?t.area/n:0;i.push(r?{index:t.index,x:u,y:s+o,width:n,height:e}:{index:t.index,x:u+o,y:s,width:e,height:n}),o+=e}r?(u+=n,c-=n):(s+=n,l-=n),h=[]};for(const t of a)0===h.length||worst([...h,t])<=worst(h)||place(),h.push(t);return h.length>0&&place(),i}const l={month:"short",day:"numeric"},h={notation:"compact",maximumFractionDigits:1},m={maximumFractionDigits:2};export function formatCategory(e,n){return e instanceof Date?t(n,l).format(e):String(e)}export function compactNumber(t,n){return Math.abs(t)>=1e4?e(n,h).format(t):e(n,m).format(t)}export function writeChartValue(t,n,r){return n?e(r,n).format(t):compactNumber(t,r)}
@@ -1 +1 @@
1
- "use client";import*as e from"react";export const DEFAULT_STORAGE_KEY="plass-color-scheme";export const darkQuery="(prefers-color-scheme: dark)";export function applyColorScheme(e){if("undefined"==typeof document)return;const t=document.documentElement;t.classList.remove("light","dark"),"system"!==e?(t.dataset.theme=e,t.classList.add(e)):delete t.dataset.theme}export function readStoredScheme(e){if("undefined"==typeof localStorage)return null;try{const t=localStorage.getItem(e);return"light"===t||"dark"===t||"system"===t?t:null}catch{return null}}const t=new Map;function storeFor(e,r){let o=t.get(e);return o||(o={scheme:readStoredScheme(e)??r,listeners:new Set},t.set(e,o)),o}export function useColorSchemeStore(t,r){const o=e.useCallback(e=>{const o=storeFor(t,r);o.listeners.add(e);const onStorage=e=>{if(e.key!==t)return;const s=readStoredScheme(t)??r;s!==o.scheme&&(o.scheme=s,applyColorScheme(s),o.listeners.forEach(e=>e()))};return window.addEventListener("storage",onStorage),()=>{o.listeners.delete(e),window.removeEventListener("storage",onStorage)}},[t,r]),s=e.useCallback(()=>storeFor(t,r).scheme,[t,r]),n=e.useCallback(()=>r,[r]),c=e.useSyncExternalStore(o,s,n),l=e.useCallback(e=>{const o=storeFor(t,r);o.scheme=e,function writeStoredScheme(e,t){try{localStorage.setItem(e,t)}catch{}}(t,e),applyColorScheme(e),o.listeners.forEach(e=>e())},[t,r]);return[c,l]}
1
+ "use client";import*as e from"react";export const DEFAULT_STORAGE_KEY="plass-color-scheme";export const darkQuery="(prefers-color-scheme: dark)";export function applyColorScheme(e){if("undefined"==typeof document)return;const t=document.documentElement;t.classList.remove("light","dark"),"system"!==e?(t.dataset.theme=e,t.classList.add(e)):delete t.dataset.theme}export function readStoredScheme(e){try{if("undefined"==typeof localStorage)return null;const t=localStorage.getItem(e);return"light"===t||"dark"===t||"system"===t?t:null}catch{return null}}const t=new Map;function storeFor(e,r){let o=t.get(e);return o||(o={scheme:readStoredScheme(e)??r,listeners:new Set},t.set(e,o)),o}export function useColorSchemeStore(t,r){const o=e.useCallback(e=>{const o=storeFor(t,r);o.listeners.add(e);const onStorage=e=>{if(e.key!==t)return;const s=readStoredScheme(t)??r;s!==o.scheme&&(o.scheme=s,applyColorScheme(s),o.listeners.forEach(e=>e()))};return window.addEventListener("storage",onStorage),()=>{o.listeners.delete(e),window.removeEventListener("storage",onStorage)}},[t,r]),s=e.useCallback(()=>storeFor(t,r).scheme,[t,r]),n=e.useCallback(()=>r,[r]),c=e.useSyncExternalStore(o,s,n),l=e.useCallback(e=>{const o=storeFor(t,r);o.scheme=e,function writeStoredScheme(e,t){try{localStorage.setItem(e,t)}catch{}}(t,e),applyColorScheme(e),o.listeners.forEach(e=>e())},[t,r]);return[c,l]}
@@ -18,7 +18,8 @@ export interface PlassSort {
18
18
  direction: PlassSortDirection;
19
19
  }
20
20
  /**
21
- * Puts two cell values in order.
21
+ * Puts two cell values in order, in the direction given: `1` for ascending and
22
+ * `-1` for descending.
22
23
  *
23
24
  * Numbers and dates compare as themselves, strings compare the way the reader's
24
25
  * language orders them, and everything else falls back to its text. Two rules
@@ -27,15 +28,15 @@ export interface PlassSort {
27
28
  * **Nothing sorts last, in both directions.** A column of amounts with three
28
29
  * blanks in it is a column whose blanks are not the smallest amounts, and a
29
30
  * reader who reversed the sort to find the largest should not be handed the
30
- * empty ones instead. So the answer for a missing value is decided here, before
31
- * the direction is applied, and the caller flips only the rest.
31
+ * empty ones instead. So the answer for a missing value is decided here, and the
32
+ * direction turns only the rest round.
32
33
  *
33
34
  * **Strings compare with `localeCompare`.** `'a' < 'B'` is false by code point,
34
35
  * which puts every capitalised word above every lower-case one and sorts `Ösi`
35
36
  * after `Zoe`. A list of names a reader cannot scan is a list that was sorted
36
37
  * for the machine.
37
38
  */
38
- export declare function compareValues(a: unknown, b: unknown): number;
39
+ export declare function compareValues(a: unknown, b: unknown, direction?: 1 | -1): number;
39
40
  /**
40
41
  * What pressing a column heading does next.
41
42
  *
@@ -1 +1 @@
1
- export function compareValues(e,n){const t=null==e||""===e,o=null==n||""===n;return t||o?t&&o?0:t?1:-1:"number"==typeof e&&"number"==typeof n?e-n:"boolean"==typeof e&&"boolean"==typeof n?Number(e)-Number(n):e instanceof Date&&n instanceof Date?e.getTime()-n.getTime():String(e).localeCompare(String(n))}export function nextSort(e,n){return null===e||e.key!==n?{key:n,direction:"asc"}:"asc"===e.direction?{key:n,direction:"desc"}:null}export function keysBetween(e,n,t){const o=e.indexOf(n),r=e.indexOf(t);return-1===o||-1===r?[]:o<=r?e.slice(o,r+1):e.slice(r,o+1)}export function pageBounds(e,n,t){const o=Math.max(1,Math.ceil(e/t)),r=(Math.min(Math.max(1,Math.trunc(n)),o)-1)*t;return[r,Math.min(r+t,e)]}
1
+ export function compareValues(e,n,t=1){const o=null==e||""===e,r=null==n||""===n;return o||r?o&&r?0:o?1:-1:function compareKnown(e,n){return"number"==typeof e&&"number"==typeof n?e-n:"boolean"==typeof e&&"boolean"==typeof n?Number(e)-Number(n):e instanceof Date&&n instanceof Date?e.getTime()-n.getTime():String(e).localeCompare(String(n))}(e,n)*t}export function nextSort(e,n){return null===e||e.key!==n?{key:n,direction:"asc"}:"asc"===e.direction?{key:n,direction:"desc"}:null}export function keysBetween(e,n,t){const o=e.indexOf(n),r=e.indexOf(t);return-1===o||-1===r?[]:o<=r?e.slice(o,r+1):e.slice(r,o+1)}export function pageBounds(e,n,t){const o=Math.max(1,Math.ceil(e/t)),r=(Math.min(Math.max(1,Math.trunc(n)),o)-1)*t;return[r,Math.min(r+t,e)]}
@@ -112,6 +112,16 @@ export declare function withTime(date: Date, parts: {
112
112
  minutes?: number;
113
113
  seconds?: number;
114
114
  }): Date;
115
+ /**
116
+ * Holds a moment inside `[min, max]`, on a whole second when `seconds` is set
117
+ * and a whole minute when it is not — the smallest step the clock can show.
118
+ *
119
+ * The bounds are read at full precision, so a moment is rounded into the span
120
+ * rather than onto a bound it would then sit outside of: up from a minimum and
121
+ * down from a maximum. Two bounds inside one step leave no whole step between
122
+ * them, and the bound itself is returned.
123
+ */
124
+ export declare function clampMoment(date: Date, min: Date | null | undefined, max: Date | null | undefined, seconds: boolean): Date;
115
125
  /** `date`'s calendar day wearing `time`'s clock. */
116
126
  export declare function mergeDateAndTime(date: Date, time: Date): Date;
117
127
  /**
@@ -1 +1 @@
1
- import{dateFormatter as t}from"./format.js";export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,r){const n=new Date(0);return n.setFullYear(t,e,r),n.setHours(0,0,0,0),n}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function startOfYear(t){return makeDate(t.getFullYear(),0,1)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const r=new Date(t.getTime());return r.setDate(r.getDate()+e),r}export function addMonths(t,e){const r=new Date(t.getTime()),n=makeDate(t.getFullYear(),t.getMonth()+e,1);return r.setFullYear(n.getFullYear(),n.getMonth(),Math.min(t.getDate(),daysInMonth(n.getFullYear(),n.getMonth()))),r}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function clampDate(t,e,r){return isValidDate(e)&&t.getTime()<e.getTime()?new Date(e.getTime()):isValidDate(r)&&t.getTime()>r.getTime()?new Date(r.getTime()):t}export function isDayOutside(t,e,r){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(r)&&compareDay(t,r)>0}export function isMonthOutside(t,e,r){const n=t.getFullYear(),o=t.getMonth();return isDayOutside(makeDate(n,o,daysInMonth(n,o)),e,null)||isDayOutside(makeDate(n,o,1),null,r)}export function isYearOutside(t,e,r){const n=t.getFullYear();return isValidDate(e)&&n<e.getFullYear()||isValidDate(r)&&n>r.getFullYear()}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const r=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(r/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(r/60);return[t,t+59]}if("second"===t)return[r,r];const n=e.getHours()<12?0:43200;return[n,n+43200-1]}export function withTime(t,e){const r=new Date(t.getTime());return r.setHours(e.hours??r.getHours(),e.minutes??r.getMinutes(),e.seconds??r.getSeconds(),0),r}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const r=startOfMonth(t),n=(r.getDay()-e+7)%7,o=addDays(r,-n);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,r)=>addDays(o,7*e+r)))}export function yearPageStart(t){return t-(t%12+12)%12}export function formatDate(e,r,n){return isValidDate(e)?t(r,n).format(e):""}const e=/* @__PURE__ */Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58));export function displaySamples(r,n){const o=t(r,n);return[...new Set(e.map(t=>o.format(t)))]}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const pad=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${pad(t.getMonth()+1)}-${pad(t.getDate())}`}export function toISOMonth(t){return`${String(t.getFullYear()).padStart(4,"0")}-${String(t.getMonth()+1).padStart(2,"0")}`}export function toISOYear(t){return String(t.getFullYear()).padStart(4,"0")}export function toISOTime(t,e=!1){const pad=t=>String(t).padStart(2,"0"),r=`${pad(t.getHours())}:${pad(t.getMinutes())}`;return e?`${r}:${pad(t.getSeconds())}`:r}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const r=/* @__PURE__ */makeDate(2021,7,1);export function weekdayLabels(e,n,o="short"){const a=t(e,{weekday:o});return Array.from({length:7},(t,e)=>a.format(addDays(r,(n+e)%7)))}export function monthLabels(e,r="short"){const n=t(e,{month:r});return Array.from({length:12},(t,e)=>n.format(makeDate(2021,e,1)))}export function isMonthBeforeYear(e){const n=t(e,{year:"numeric",month:"long"}).formatToParts(r);return n.findIndex(t=>"month"===t.type)<n.findIndex(t=>"year"===t.type)}export function isHour12(e){const r=t(e,{hour:"numeric"}).resolvedOptions();return r.hourCycle?"h11"===r.hourCycle||"h12"===r.hourCycle:!0===r.hour12}export function meridiemLabels(e){const n=t(e,{hour:"numeric",hour12:!0}),read=t=>{const e=n.formatToParts(withTime(r,{hours:t})).find(t=>"dayPeriod"===t.type);return e?.value??(t<12?"AM":"PM")};return[read(9),read(21)]}export function localeWeekStart(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,r=new Intl.Locale(e),n="function"==typeof r.getWeekInfo?r.getWeekInfo():r.weekInfo;if("number"==typeof n?.firstDay)return n.firstDay%7}catch{}return 0}
1
+ import{dateFormatter as t}from"./format.js";export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,n){const r=new Date(0);return r.setFullYear(t,e,n),r.setHours(0,0,0,0),r}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function startOfYear(t){return makeDate(t.getFullYear(),0,1)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const n=new Date(t.getTime());return n.setDate(n.getDate()+e),n}export function addMonths(t,e){const n=new Date(t.getTime()),r=makeDate(t.getFullYear(),t.getMonth()+e,1);return n.setFullYear(r.getFullYear(),r.getMonth(),Math.min(t.getDate(),daysInMonth(r.getFullYear(),r.getMonth()))),n}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function clampDate(t,e,n){return isValidDate(e)&&t.getTime()<e.getTime()?new Date(e.getTime()):isValidDate(n)&&t.getTime()>n.getTime()?new Date(n.getTime()):t}export function isDayOutside(t,e,n){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(n)&&compareDay(t,n)>0}export function isMonthOutside(t,e,n){const r=t.getFullYear(),o=t.getMonth();return isDayOutside(makeDate(r,o,daysInMonth(r,o)),e,null)||isDayOutside(makeDate(r,o,1),null,n)}export function isYearOutside(t,e,n){const r=t.getFullYear();return isValidDate(e)&&r<e.getFullYear()||isValidDate(n)&&r>n.getFullYear()}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const n=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(n/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(n/60);return[t,t+59]}if("second"===t)return[n,n];const r=e.getHours()<12?0:43200;return[r,r+43200-1]}export function withTime(t,e){const n=new Date(t.getTime());return n.setHours(e.hours??n.getHours(),e.minutes??n.getMinutes(),e.seconds??n.getSeconds(),0),n}export function clampMoment(t,e,n,r){const o=r?1e3:6e4,floor=t=>withTime(t,{seconds:r?t.getSeconds():0});if(isValidDate(e)&&t.getTime()<e.getTime()){const t=floor(e),r=t.getTime()<e.getTime()?new Date(t.getTime()+o):t;return isValidDate(n)&&r.getTime()>n.getTime()?new Date(e.getTime()):r}if(isValidDate(n)&&t.getTime()>n.getTime()){const t=floor(n);return isValidDate(e)&&t.getTime()<e.getTime()?new Date(n.getTime()):t}return t}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const n=startOfMonth(t),r=(n.getDay()-e+7)%7,o=addDays(n,-r);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,n)=>addDays(o,7*e+n)))}export function yearPageStart(t){return t-(t%12+12)%12}export function formatDate(e,n,r){return isValidDate(e)?t(n,r).format(e):""}const e=/* @__PURE__ */[...Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58)),new Date(2027,0,22,12,58,58)];export function displaySamples(n,r){const o=t(n,r);return[...new Set(e.map(t=>o.format(t)))]}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const pad=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${pad(t.getMonth()+1)}-${pad(t.getDate())}`}export function toISOMonth(t){return`${String(t.getFullYear()).padStart(4,"0")}-${String(t.getMonth()+1).padStart(2,"0")}`}export function toISOYear(t){return String(t.getFullYear()).padStart(4,"0")}export function toISOTime(t,e=!1){const pad=t=>String(t).padStart(2,"0"),n=`${pad(t.getHours())}:${pad(t.getMinutes())}`;return e?`${n}:${pad(t.getSeconds())}`:n}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const n=/* @__PURE__ */makeDate(2021,7,1);export function weekdayLabels(e,r,o="short"){const a=t(e,{weekday:o});return Array.from({length:7},(t,e)=>a.format(addDays(n,(r+e)%7)))}export function monthLabels(e,n="short"){const r=t(e,{month:n});return Array.from({length:12},(t,e)=>r.format(makeDate(2021,e,1)))}export function isMonthBeforeYear(e){const r=t(e,{year:"numeric",month:"long"}).formatToParts(n);return r.findIndex(t=>"month"===t.type)<r.findIndex(t=>"year"===t.type)}export function isHour12(e){const n=t(e,{hour:"numeric"}).resolvedOptions();return n.hourCycle?"h11"===n.hourCycle||"h12"===n.hourCycle:!0===n.hour12}export function meridiemLabels(e){const r=t(e,{hour:"numeric",hour12:!0}),read=t=>{const e=r.formatToParts(withTime(n,{hours:t})).find(t=>"dayPeriod"===t.type);return e?.value??(t<12?"AM":"PM")};return[read(9),read(21)]}export function localeWeekStart(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,n=new Intl.Locale(e),r="function"==typeof n.getWeekInfo?n.getWeekInfo():n.weekInfo;if("number"==typeof r?.firstDay)return r.firstDay%7}catch{}return 0}
@@ -31,7 +31,7 @@
31
31
  import * as React from 'react';
32
32
  import type { PlassLabels } from './labels.js';
33
33
  import type { PlassDirection } from './direction.js';
34
- import type { PlassColor, PlassDensity, PlassSize, PlassWeekday } from '../types.js';
34
+ import type { PlassColor, PlassDensity, PlassFieldLabelPlacement, PlassSize, PlassWeekday } from '../types.js';
35
35
  /** Everything a `PlassProvider` can decide for the tree under it. */
36
36
  export interface PlassDefaults {
37
37
  /** The rung of the size ladder every component starts from. */
@@ -40,6 +40,19 @@ export interface PlassDefaults {
40
40
  color?: PlassColor;
41
41
  /** How tightly they pack their content. */
42
42
  density?: PlassDensity;
43
+ /**
44
+ * Where a labelled control puts its label — above the box, or in the box's
45
+ * top edge.
46
+ *
47
+ * Here for the same reason `density` is: a product whose forms notch their
48
+ * labels notches all of them, and the decision is the application's rather
49
+ * than the field's. A component's own `labelPlacement` still wins, which is
50
+ * what a form with one field that genuinely cannot take a notch needs.
51
+ *
52
+ * `PlOtpField` is not reached by it: a row of separate boxes has no one edge
53
+ * to cut, so its label stays above the row whatever this says.
54
+ */
55
+ labelPlacement?: PlassFieldLabelPlacement;
43
56
  /** The BCP 47 tag the date and time components format and read against. */
44
57
  locale?: string;
45
58
  /** Which day their weeks start on, as `Date` counts them — Sunday is `0`. */
@@ -14,6 +14,22 @@
14
14
  * nothing and cost a frame of latency on the one gesture where latency is the
15
15
  * whole feel of it.
16
16
  */
17
+ /**
18
+ * The selection, taken for the length of a gesture.
19
+ *
20
+ * Written prefixed and through `setProperty` because WebKit implements only
21
+ * `-webkit-user-select`: `style.userSelect = 'none'` hangs a plain JavaScript
22
+ * property off the object, changes nothing, and Safari goes on selecting text
23
+ * through the whole drag. It is taken off the document rather than fixed with
24
+ * `preventDefault`, which would also stop the browser focusing what was
25
+ * pressed and leave every mouse press wearing a keyboard focus ring.
26
+ *
27
+ * Exported as well as used below, for the gesture that takes the selection at a
28
+ * moment of its own rather than at the press: `PlScrollZone` waits for the
29
+ * pointer to pass its threshold, because up to that point the press is still a
30
+ * click on a card and the reader is still allowed to select the text under it.
31
+ */
32
+ export declare function takeSelection(): () => void;
17
33
  export interface PointerDragOptions {
18
34
  /**
19
35
  * The element the three listeners go on, and the one the pointer is captured
@@ -1 +1 @@
1
- export function beginPointerDrag({target:e,pointerId:t,onMove:n,onEnd:r,selectable:o=!0,mark:s=!0}){const i=o?function takeSelection(){const e=document.body,t=e.style.getPropertyValue("-webkit-user-select");return e.style.setProperty("-webkit-user-select","none"),()=>{t?e.style.setProperty("-webkit-user-select",t):e.style.removeProperty("-webkit-user-select")}}():null;s&&(e.dataset.dragging="true"),e.setPointerCapture?.(t);let a=!0;const release=()=>{a&&(a=!1,e.removeEventListener("pointermove",n),e.removeEventListener("pointerup",end),e.removeEventListener("pointercancel",end),s&&delete e.dataset.dragging,i?.())},end=()=>{release(),r?.()};return e.addEventListener("pointermove",n),e.addEventListener("pointerup",end),e.addEventListener("pointercancel",end),release}
1
+ export function takeSelection(){const e=document.body,t=e.style.getPropertyValue("-webkit-user-select");return e.style.setProperty("-webkit-user-select","none"),()=>{t?e.style.setProperty("-webkit-user-select",t):e.style.removeProperty("-webkit-user-select")}}export function beginPointerDrag({target:e,pointerId:t,onMove:n,onEnd:r,selectable:o=!0,mark:s=!0}){const i=o?takeSelection():null;s&&(e.dataset.dragging="true"),e.setPointerCapture?.(t);let a=!0;const release=()=>{a&&(a=!1,e.removeEventListener("pointermove",n),e.removeEventListener("pointerup",end),e.removeEventListener("pointercancel",end),s&&delete e.dataset.dragging,i?.())},end=()=>{release(),r?.()};return e.addEventListener("pointermove",n),e.addEventListener("pointerup",end),e.addEventListener("pointercancel",end),release}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Every element under `root` that the Tab key could land on, in document order.
3
+ *
4
+ * Anything inside an `inert` subtree is left out: it matches the selector and
5
+ * a browser still refuses to focus it, so handing the focus to one is handing
6
+ * it to the top of the document.
7
+ */
8
+ export declare function focusablesIn(root: ParentNode): HTMLElement[];
@@ -0,0 +1 @@
1
+ export function focusablesIn(e){return Array.from(e.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(e=>!e.closest("[inert]"))}
@@ -0,0 +1,61 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * How a control whose visible part is not an `<input>` takes part in a form.
4
+ *
5
+ * Base UI's `Form` validates, focuses and collects only the controls registered
6
+ * with a `Field`, and the one public way to register is `Field.Control`, which
7
+ * is an `<input>` holding a string. A picker's trigger is a button and a file
8
+ * picker's is a drop zone, so on their own they were invisible to a `PlForm`:
9
+ * missing from its values, never blocking a submit, and never showing the error
10
+ * it had for their `name`.
11
+ *
12
+ * `FormControl` is that input, kept off screen. It holds the value as a string,
13
+ * so `required` is the browser's own check, and it hands the focus a form moves
14
+ * to it on to the control a reader actually uses. What a string cannot carry —
15
+ * the two ends of a range, several selections, a list of files — is reported to
16
+ * the `PlForm` around it through `useFormReport`, and `PlForm` lays those over
17
+ * the values Base UI collected.
18
+ */
19
+ /** Values reported to a `PlForm` by name, read when the form is submitted. */
20
+ export type FormReport = Map<string, () => unknown>;
21
+ export declare const FormReportContext: React.Context<FormReport | null>;
22
+ /**
23
+ * Reports `read()` as the value of `name` to the `PlForm` around the caller,
24
+ * for as long as `enabled` holds. Outside a `PlForm` it does nothing.
25
+ */
26
+ export declare function useFormReport(name: string | undefined, read: () => unknown, enabled?: boolean): void;
27
+ /**
28
+ * Whether `element` is inside a disabled `<fieldset>`, re-rendering when a
29
+ * fieldset around it turns `disabled` on or off.
30
+ *
31
+ * The browser disables a native control inside one by itself. A control drawn
32
+ * as elements with a `tabIndex` is not a form control, so the fieldset never
33
+ * reaches it and it has to ask. The answer is the platform's: a disabled
34
+ * fieldset reaches everything inside it except what is in its first `<legend>`.
35
+ */
36
+ export declare function useFieldsetDisabled(element: Element | null): boolean;
37
+ /**
38
+ * Tells a `FormControl` the reader has left the control it stands behind, so a
39
+ * form that validates on blur checks it then. The input never has the focus
40
+ * itself, so the event it would have had is sent to it.
41
+ */
42
+ export declare function leaveFormControl(input: HTMLInputElement | null): void;
43
+ export interface FormControlProps {
44
+ /** The name the value submits under, and the key a form's `errors` use. */
45
+ name?: string;
46
+ /**
47
+ * The value as a form submits it: one string, or one entry per row. An empty
48
+ * string, a list with an empty entry and an empty list are no value, which is
49
+ * what `required` checks.
50
+ */
51
+ value: string | readonly string[];
52
+ required: boolean;
53
+ disabled: boolean;
54
+ /** The element a reader uses, which takes the focus a form moves here. */
55
+ standIn: () => HTMLElement | null | undefined;
56
+ }
57
+ /**
58
+ * The input a `Field` registers for a control that is not one. Renders inside a
59
+ * `Field.Root`.
60
+ */
61
+ export declare const FormControl: React.ForwardRefExoticComponent<FormControlProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{Field as o}from"@base-ui/react/field";export const FormReportContext=/* @__PURE__ */n.createContext(null);export function useFormReport(e,t,r=!0){const o=n.useContext(FormReportContext),s=n.useRef(t);n.useEffect(()=>{s.current=t}),n.useEffect(()=>{if(!o||!e||!r)return;const entry=()=>s.current();return o.set(e,entry),()=>{o.get(e)===entry&&o.delete(e)}},[o,e,r])}function fieldsetsAround(e){const t=[];for(let r=e.parentElement?.closest("fieldset");r;r=r.parentElement?.closest("fieldset"))t.push(r);return t}export function useFieldsetDisabled(e){const t=n.useCallback(t=>{if(!e)return()=>{};const r=new MutationObserver(t);return fieldsetsAround(e).forEach(e=>r.observe(e,{attributes:!0,attributeFilter:["disabled"]})),()=>r.disconnect()},[e]);return n.useSyncExternalStore(t,()=>null!==e&&fieldsetsAround(e).some(t=>t.disabled&&!t.querySelector(":scope > legend")?.contains(e)),()=>!1)}export function leaveFormControl(e){e?.dispatchEvent(new FocusEvent("focusout",{bubbles:!0}))}export const FormControl=/* @__PURE__ */n.forwardRef(function FormControl({name:n,value:s,required:u,disabled:i,standIn:a},l){const c=Array.isArray(s),d=c?s.length>0&&s.every(e=>""!==e):""!==s;return useFormReport(n,()=>[...s],c&&!i),r(t,{children:[e(o.Control,{ref:l,name:n,value:c?d?s.join("\n"):"":s,required:u,disabled:i,tabIndex:-1,"aria-hidden":"true",autoComplete:"off",className:"pointer-events-none absolute size-px overflow-hidden opacity-0 [clip-path:inset(50%)]",onFocus:()=>a()?.focus(),render:c?t=>e("input",{...t,name:void 0}):void 0}),c&&n?s.map((t,r)=>e("input",{type:"hidden",name:n,value:t,disabled:i},r)):null]})});
@@ -1,17 +1,3 @@
1
- /**
2
- * The arithmetic a `PlGallery` lays itself out with.
3
- *
4
- * It is here rather than in the component for the reason `internal/steps.ts`
5
- * is: **the Dart build needs the same answers.** A masonry that dealt its
6
- * columns differently on the two sides would be one gallery with two orders,
7
- * and the order is the only thing about a masonry a reader can check.
8
- *
9
- * Nothing in here measures anything. Every function takes the ratios the caller
10
- * declared, which is what lets the whole arrangement be right in the first
11
- * frame the browser paints and stay put as the files arrive — the bargain
12
- * `PlImage`'s own `ratio` makes, one level up, and the reason a gallery of
13
- * forty photographs does not reflow forty times.
14
- */
15
1
  /**
16
2
  * A tile's proportion as the number the layouts do arithmetic on.
17
3
  *
@@ -19,6 +5,23 @@
19
5
  * one and this library does not make a caller translate it.
20
6
  */
21
7
  export declare function ratioOf(value: number | string | undefined, fallback: number): number;
8
+ /**
9
+ * Whether an item's picture is turned onto its side.
10
+ *
11
+ * The gallery and its viewer both ask, so they ask here: a tile laid out on its
12
+ * side that opened upright, or the other way round, would be one picture shown
13
+ * two ways.
14
+ */
15
+ export declare function isTurned(rotate: number | undefined): boolean;
16
+ /**
17
+ * The proportion an item is shown at: its file's own, or the inverse for a
18
+ * picture on its side.
19
+ *
20
+ * An item's `ratio` stays the stored file's proportion, which is what a caller
21
+ * has to hand, so every piece of layout arithmetic that runs before anything
22
+ * loads reads it through this.
23
+ */
24
+ export declare function shownRatio(ratio: number, rotate: number | undefined): number;
22
25
  /**
23
26
  * The items dealt into columns, shortest column first.
24
27
  *
@@ -32,3 +35,46 @@ export declare function ratioOf(value: number | string | undefined, fallback: nu
32
35
  * this run on the server and hold still while the files arrive.
33
36
  */
34
37
  export declare function dealColumns(ratios: readonly number[], columns: number): number[][];
38
+ /**
39
+ * One row track of a masonry: a share of the column width, the height of the
40
+ * captions that end there, or the gap.
41
+ */
42
+ export type PlassMasonryTrack = number | 'caption' | 'gap';
43
+ /** Where one tile sits in a masonry's grid, as `grid-column` and `grid-row` count. */
44
+ export interface PlassMasonryTile {
45
+ /** The lane, from 1. */
46
+ column: number;
47
+ /** The row line the tile starts on. */
48
+ start: number;
49
+ /** The row line it ends on. */
50
+ end: number;
51
+ }
52
+ /**
53
+ * The same deal as `dealColumns`, written as the rows of one CSS grid rather
54
+ * than as a list per lane.
55
+ *
56
+ * A list per lane put the document in lane order: Tab went 1, 4, 7 through
57
+ * twelve pictures in three lanes, and a tile that changed lane when the count
58
+ * did was a new element, with its picture's state thrown away. Placed in one
59
+ * grid, every tile stays where it was given and only its placement changes.
60
+ * The web build needs this and the Dart build does not, because a Flutter
61
+ * layout is not a document.
62
+ *
63
+ * Every edge where a tile ends, in any lane, is a row line. The track up to it
64
+ * is a share, sized in `fr` by its distance from the edge before, in column
65
+ * widths. In a grid whose height is its content every `fr` then comes out one
66
+ * column width long, so a tile spanning its shares is exactly as tall as its
67
+ * picture. After the share come the captions that end on that edge, in a track
68
+ * of their own so their height is not spread over the pictures, and then the
69
+ * gap, when a tile starts there.
70
+ *
71
+ * What a stylesheet cannot know is where an edge in one lane falls among the
72
+ * edges of another once the gaps and captions are added, because that depends
73
+ * on the width. A tile that runs past the end of a tile in another lane spans
74
+ * that tile's caption and gap tracks as well, and is that much taller than its
75
+ * picture.
76
+ */
77
+ export declare function masonryRows(ratios: readonly number[], columns: number, captions: boolean): {
78
+ tracks: PlassMasonryTrack[];
79
+ tiles: PlassMasonryTile[];
80
+ };
@@ -1 +1 @@
1
- export function ratioOf(r,e){if(void 0===r)return e;if("number"==typeof r)return r>0?r:e;const[t,n]=r.split("/"),o=void 0===n?Number(t):Number(t)/Number(n);return Number.isFinite(o)&&o>0?o:e}export function dealColumns(r,e){const t=Array.from({length:e},()=>[]),n=new Array(e).fill(0);return r.forEach((r,o)=>{let u=0;for(let r=1;r<e;r+=1)n[r]<n[u]&&(u=r);t[u].push(o),n[u]+=1/r}),t}
1
+ import{isSideways as t,quartersOf as r}from"./image.js";export function ratioOf(t,r){if(void 0===t)return r;if("number"==typeof t)return t>0?t:r;const[n,o]=t.split("/"),e=void 0===o?Number(n):Number(n)/Number(o);return Number.isFinite(e)&&e>0?e:r}export function isTurned(n){return void 0!==n&&t(r(n))}export function shownRatio(t,r){return isTurned(r)?1/t:t}export function dealColumns(t,r){const n=Array.from({length:r},()=>[]),o=new Array(r).fill(0);return t.forEach((t,e)=>{let s=0;for(let t=1;t<r;t+=1)o[t]<o[s]&&(s=t);n[s].push(e),o[s]+=1/t}),n}export function masonryRows(t,r,n){const o=dealColumns(t,r),e=[],s=[],u=[];o.forEach((r,n)=>{let o=0;r.forEach((i,a)=>{o+=1/t[i],e[i]=n,s[i]=o,u[i]=0===a?-1:r[a-1]})});const i=[],a=[];for(const r of t.map((t,r)=>r).sort((t,r)=>s[t]-s[r]))(0===i.length||s[r]-i[i.length-1]>.001)&&i.push(s[r]),a[r]=i.length-1;const f=new Set(u.filter(t=>-1!==t).map(t=>a[t])),c=[],l=[],p=[];i.forEach((t,r)=>{c.push(t-(0===r?0:i[r-1])),n&&c.push("caption"),l[r]=c.length+1,f.has(r)&&c.push("gap"),p[r]=c.length+1});const h=t.map((t,r)=>({column:e[r]+1,start:-1===u[r]?1:p[a[u[r]]],end:l[a[r]]}));return{tracks:c,tiles:h}}
@@ -0,0 +1,32 @@
1
+ import type * as React from 'react';
2
+ /**
3
+ * Moves `.plass-glow`'s light to where the pointer is on the surface.
4
+ *
5
+ * Written straight to the element as `--p-mx` and `--p-my` rather than held in
6
+ * state: it runs at pointer rate, and a `setState` here would re-render the
7
+ * tree on every mouse move. It also runs while a finger is down, which is what
8
+ * makes the light follow a drag on a touch screen, where there is no hover and
9
+ * the `:active` layer does the work.
10
+ *
11
+ * `offsetX` and `offsetY` cost nothing, but they are measured from whatever the
12
+ * pointer is over. On a surface whose own element is under the pointer — a
13
+ * button, whose icons ignore the pointer — that is the surface, and they are
14
+ * used as they are. On one that holds other elements the pointer can land on,
15
+ * the position is read against the surface's own box instead.
16
+ */
17
+ export declare function followPointer(event: React.PointerEvent<HTMLElement>): void;
18
+ /**
19
+ * `.plass-glow` and the `pointermove` that feeds it, composed with whatever
20
+ * handler the caller already passed.
21
+ *
22
+ * Every surface that carries the light needs the same three things: the class,
23
+ * `position: relative` for the two layers to hang off, and this handler. The
24
+ * class and `relative` are written into each component's own base classes,
25
+ * because Tailwind only generates what it has seen spelled out; the wiring is
26
+ * here, so that every call site does not grow its own copy of it.
27
+ *
28
+ * `undefined` comes back when the surface is not interactive and the caller
29
+ * passed nothing, which is what keeps a listener off an element that has no
30
+ * light to move.
31
+ */
32
+ export declare function glowPointerMove<E extends HTMLElement>(lit: boolean, onPointerMove?: React.PointerEventHandler<E>): React.PointerEventHandler<E> | undefined;
@@ -0,0 +1 @@
1
+ export function followPointer(t){const e=t.currentTarget;let o=t.nativeEvent.offsetX,n=t.nativeEvent.offsetY;if(t.target!==e){const r=e.getBoundingClientRect();o=t.clientX-r.left,n=t.clientY-r.top}e.style.setProperty("--p-mx",`${o}px`),e.style.setProperty("--p-my",`${n}px`)}export function glowPointerMove(t,e){return t?t=>{followPointer(t),e?.(t)}:e}
@@ -1 +1 @@
1
- const i={bash:()=>import("highlight.js/lib/languages/bash"),c:()=>import("highlight.js/lib/languages/c"),cpp:()=>import("highlight.js/lib/languages/cpp"),csharp:()=>import("highlight.js/lib/languages/csharp"),css:()=>import("highlight.js/lib/languages/css"),dart:()=>import("highlight.js/lib/languages/dart"),diff:()=>import("highlight.js/lib/languages/diff"),dockerfile:()=>import("highlight.js/lib/languages/dockerfile"),go:()=>import("highlight.js/lib/languages/go"),graphql:()=>import("highlight.js/lib/languages/graphql"),ini:()=>import("highlight.js/lib/languages/ini"),java:()=>import("highlight.js/lib/languages/java"),javascript:()=>import("highlight.js/lib/languages/javascript"),json:()=>import("highlight.js/lib/languages/json"),kotlin:()=>import("highlight.js/lib/languages/kotlin"),less:()=>import("highlight.js/lib/languages/less"),lua:()=>import("highlight.js/lib/languages/lua"),makefile:()=>import("highlight.js/lib/languages/makefile"),markdown:()=>import("highlight.js/lib/languages/markdown"),objectivec:()=>import("highlight.js/lib/languages/objectivec"),perl:()=>import("highlight.js/lib/languages/perl"),php:()=>import("highlight.js/lib/languages/php"),plaintext:()=>import("highlight.js/lib/languages/plaintext"),powershell:()=>import("highlight.js/lib/languages/powershell"),python:()=>import("highlight.js/lib/languages/python"),r:()=>import("highlight.js/lib/languages/r"),ruby:()=>import("highlight.js/lib/languages/ruby"),rust:()=>import("highlight.js/lib/languages/rust"),scss:()=>import("highlight.js/lib/languages/scss"),shell:()=>import("highlight.js/lib/languages/shell"),sql:()=>import("highlight.js/lib/languages/sql"),swift:()=>import("highlight.js/lib/languages/swift"),typescript:()=>import("highlight.js/lib/languages/typescript"),xml:()=>import("highlight.js/lib/languages/xml"),yaml:()=>import("highlight.js/lib/languages/yaml")},t={"c++":"cpp",cc:"cpp",cjs:"javascript",console:"bash",cs:"csharp",cts:"typescript",docker:"dockerfile",gql:"graphql",golang:"go",h:"cpp",hpp:"cpp",htm:"xml",html:"xml",js:"javascript",jsx:"javascript",kt:"kotlin",kts:"kotlin",md:"markdown",mdx:"markdown",mjs:"javascript",mm:"objectivec",mts:"typescript",mysql:"sql",node:"javascript",none:"plaintext",objc:"objectivec",plain:"plaintext",posh:"powershell",ps1:"powershell",psql:"sql",py:"python",rb:"ruby",rs:"rust",sh:"bash",svelte:"xml",svg:"xml",text:"plaintext",toml:"ini",ts:"typescript",tsx:"typescript",txt:"plaintext",vue:"xml",yml:"yaml",zsh:"bash"},l=new Map;export function registerLanguage(i,t){const g=i.toLowerCase();l.set(g,t),s.delete(g)}let g=null;const s=new Map;export function canonicalLanguage(i){if(!i)return null;const l=i.trim().toLowerCase();return l?t[l]??l:null}export async function highlight(t,a){let e=s.get(a);e||(e=async function prepare(t){const s=l.get(t),a=s?void 0:i[t];if(!s&&!a)return null;g??=import("highlight.js/lib/core").then(i=>i.default);const e=await g;return s?e.registerLanguage(t,s):e.getLanguage(t)||e.registerLanguage(t,(await a()).default),t}(a).catch(i=>{throw s.delete(a),i}),s.set(a,e));const h=await e;return h&&g?tokenize((await g).highlight(t,{language:h,ignoreIllegals:!0}).value):null}const a={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#x27;":"'"};export function tokenize(i){const t=[[]],l=[],g=/<span class="([^"]*)">|<\/span>/g;let s=0;const push=i=>{if(!i)return;const g=l[l.length-1];i.replace(/&(?:amp|lt|gt|quot|#x27);/g,i=>a[i]).split("\n").forEach((i,l)=>{l>0&&t.push([]),i&&t[t.length-1].push(g?{text:i,token:g}:{text:i})})};for(const t of i.matchAll(g))push(i.slice(s,t.index)),s=t.index+t[0].length,void 0===t[1]?l.pop():l.push(t[1]);return push(i.slice(s)),t}export function plainLines(i){return i.split("\n").map(i=>i?[{text:i}]:[])}
1
+ const i={bash:()=>import("highlight.js/lib/languages/bash"),c:()=>import("highlight.js/lib/languages/c"),cpp:()=>import("highlight.js/lib/languages/cpp"),csharp:()=>import("highlight.js/lib/languages/csharp"),css:()=>import("highlight.js/lib/languages/css"),dart:()=>import("highlight.js/lib/languages/dart"),diff:()=>import("highlight.js/lib/languages/diff"),dockerfile:()=>import("highlight.js/lib/languages/dockerfile"),go:()=>import("highlight.js/lib/languages/go"),graphql:()=>import("highlight.js/lib/languages/graphql"),ini:()=>import("highlight.js/lib/languages/ini"),java:()=>import("highlight.js/lib/languages/java"),javascript:()=>import("highlight.js/lib/languages/javascript"),json:()=>import("highlight.js/lib/languages/json"),kotlin:()=>import("highlight.js/lib/languages/kotlin"),less:()=>import("highlight.js/lib/languages/less"),lua:()=>import("highlight.js/lib/languages/lua"),makefile:()=>import("highlight.js/lib/languages/makefile"),markdown:()=>import("highlight.js/lib/languages/markdown"),objectivec:()=>import("highlight.js/lib/languages/objectivec"),perl:()=>import("highlight.js/lib/languages/perl"),php:()=>import("highlight.js/lib/languages/php"),plaintext:()=>import("highlight.js/lib/languages/plaintext"),powershell:()=>import("highlight.js/lib/languages/powershell"),python:()=>import("highlight.js/lib/languages/python"),r:()=>import("highlight.js/lib/languages/r"),ruby:()=>import("highlight.js/lib/languages/ruby"),rust:()=>import("highlight.js/lib/languages/rust"),scss:()=>import("highlight.js/lib/languages/scss"),shell:()=>import("highlight.js/lib/languages/shell"),sql:()=>import("highlight.js/lib/languages/sql"),swift:()=>import("highlight.js/lib/languages/swift"),typescript:()=>import("highlight.js/lib/languages/typescript"),xml:()=>import("highlight.js/lib/languages/xml"),yaml:()=>import("highlight.js/lib/languages/yaml")},t={"c++":"cpp",cc:"cpp",cjs:"javascript",console:"bash",cs:"csharp",cts:"typescript",docker:"dockerfile",gql:"graphql",golang:"go",h:"cpp",hpp:"cpp",htm:"xml",html:"xml",js:"javascript",jsx:"javascript",kt:"kotlin",kts:"kotlin",md:"markdown",mdx:"markdown",mjs:"javascript",mm:"objectivec",mts:"typescript",mysql:"sql",node:"javascript",none:"plaintext",objc:"objectivec",plain:"plaintext",posh:"powershell",ps1:"powershell",psql:"sql",py:"python",rb:"ruby",rs:"rust",sh:"bash",svelte:"xml",svg:"xml",text:"plaintext",toml:"ini",ts:"typescript",tsx:"typescript",txt:"plaintext",vue:"xml",yml:"yaml",zsh:"bash"},l=new Map;export function registerLanguage(i,t){const g=i.toLowerCase();l.set(g,t),s.delete(g)}let g=null;const s=new Map;export function canonicalLanguage(i){if(!i)return null;const g=i.trim().toLowerCase();return g?l.has(g)?g:t[g]??g:null}export async function highlight(t,a){let e=s.get(a);e||(e=async function prepare(t){const s=l.get(t),a=s?void 0:i[t];if(!s&&!a)return null;g??=import("highlight.js/lib/core").then(i=>i.default);const e=await g;return s?e.registerLanguage(t,s):e.getLanguage(t)||e.registerLanguage(t,(await a()).default),t}(a).catch(i=>{throw s.delete(a),i}),s.set(a,e));const h=await e;return h&&g?tokenize((await g).highlight(t,{language:h,ignoreIllegals:!0}).value):null}const a={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#x27;":"'"};export function tokenize(i){const t=[[]],l=[],g=/<span class="([^"]*)">|<\/span>/g;let s=0;const push=i=>{if(!i)return;const g=l[l.length-1];i.replace(/&(?:amp|lt|gt|quot|#x27);/g,i=>a[i]).split("\n").forEach((i,l)=>{l>0&&t.push([]),i&&t[t.length-1].push(g?{text:i,token:g}:{text:i})})};for(const t of i.matchAll(g))push(i.slice(s,t.index)),s=t.index+t[0].length,void 0===t[1]?l.pop():l.push(t[1]);return push(i.slice(s)),t}export function plainLines(i){return i.split("\n").map(i=>i?[{text:i}]:[])}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * The arithmetic a `PlImage` turns, mirrors and places its picture with, and the
3
+ * declarations that draw the turn and the mirror.
4
+ *
5
+ * The arithmetic is here rather than in the component for the reason
6
+ * `internal/gallery.ts` is: **the Dart build needs the same answers.** A turn
7
+ * that rounded a stray `45` to a different quarter on the two sides would be one
8
+ * picture lying two different ways, and a crop that kept a different part of it
9
+ * would be two pictures. The declarations are here because the preview draws
10
+ * the same turn and mirror from a chunk of its own.
11
+ */
12
+ import type * as React from 'react';
13
+ /** A turn, as a count of clockwise quarters. */
14
+ export type PlassQuarters = 0 | 1 | 2 | 3;
15
+ /**
16
+ * Which way a picture is mirrored, along the axes it is shown on.
17
+ *
18
+ * Declared here rather than beside the component because the declarations
19
+ * below are written from it; `PlImageFlip` is this under the component's name.
20
+ */
21
+ export type PlassImageFlip = 'none' | 'horizontal' | 'vertical' | 'both';
22
+ /**
23
+ * A turn in degrees as a count of clockwise quarters, whatever number arrived.
24
+ *
25
+ * The type holds a TypeScript caller to `0`, `90`, `180` and `270`; this is for
26
+ * everyone else. `-90` is the `270` it means, `450` is `90`, anything between
27
+ * two quarters goes to the nearer one, and a number that is not finite is no
28
+ * turn at all.
29
+ */
30
+ export declare function quartersOf(degrees: number): PlassQuarters;
31
+ /** Whether a turn puts the picture on its side, swapping its width and height. */
32
+ export declare function isSideways(quarters: PlassQuarters): boolean;
33
+ /**
34
+ * The turn and the mirror, as the declarations that draw them.
35
+ *
36
+ * The individual `rotate` and `scale` properties rather than `transform`, which
37
+ * leaves `transform` to whoever else wants the picture: an inline `transform`
38
+ * here would silently beat a hover effect or a class of the caller's own.
39
+ *
40
+ * The two compose in a fixed order, and scale comes first: it acts on the
41
+ * element before the element is turned. So on a quarter turn, a mirror along one
42
+ * axis of the screen is a mirror along the other axis of the element, and the
43
+ * two are swapped here rather than making a caller think about it.
44
+ *
45
+ * On its side the picture is laid out at the box's height by the box's width
46
+ * and turned into place, and that is what lets `fit` work at all. `object-fit`
47
+ * fits the element's own box, and a picture turned inside the box it was given
48
+ * would overhang it on one axis and fall short on the other. The container
49
+ * units read the box, which is a size container only while this is the case;
50
+ * `maxWidth` is cleared because a reset caps an `<img>` at the width of its
51
+ * parent, and on a tall box that is shorter than the length the turned picture
52
+ * needs.
53
+ */
54
+ export declare function poseStyle(quarters: PlassQuarters, flip: PlassImageFlip): React.CSSProperties | null;
55
+ /**
56
+ * The geometry of a copy of the picture drawn underneath it: the same turn and
57
+ * mirror, over the same box grown by `bleed` on every side.
58
+ *
59
+ * A blur fades to transparent over about two of its radii at the element's
60
+ * edge, so a blurred copy drawn at the box's own size would show the page
61
+ * through a soft frame. Grown past the box, it has the fringe clipped off by the
62
+ * box's `overflow: hidden` instead.
63
+ */
64
+ export declare function layerStyle(quarters: PlassQuarters, flip: PlassImageFlip, bleed: number): React.CSSProperties;
65
+ /**
66
+ * A position as the fractions of the free space across and down, or `null` for
67
+ * anything past the keywords and percentages `PlImagePosition` offers.
68
+ *
69
+ * The part of CSS's grammar a caller writes. A keyword says its own axis, a
70
+ * percentage is across when it comes first and down when it comes second, and
71
+ * `center` says nothing, which leaves the axis at the middle. A length has no
72
+ * fraction to turn, so it is `null`.
73
+ */
74
+ export declare function positionFractions(position: string): [number, number] | null;
75
+ /**
76
+ * A place on the picture as it is shown, as the same place on the element that
77
+ * is actually turned and mirrored.
78
+ *
79
+ * `object-position` works in the element's own frame, before it is transformed,
80
+ * so `top` on a picture turned upside down would keep what ends up at the
81
+ * bottom. The mirror is undone first, because it acts on the axes of the screen
82
+ * after the turn. Then the turn, a quarter at a time: one quarter clockwise lays
83
+ * the element's left edge along the top of the screen, so what is across on the
84
+ * screen was down the element.
85
+ */
86
+ export declare function elementFractions([shownAcross, shownDown]: readonly [number, number], quarters: PlassQuarters, mirrorAcross: boolean, mirrorDown: boolean): [number, number];
87
+ /**
88
+ * The `object-position` that keeps `position` where the reader sees it.
89
+ *
90
+ * Always written as two percentages rounded to two decimals, which every engine
91
+ * serialises the same way. A string the parser cannot read is handed through as
92
+ * it was written.
93
+ */
94
+ export declare function objectPosition(position: string, quarters: PlassQuarters, flip: PlassImageFlip): string;
@@ -0,0 +1 @@
1
+ export function quartersOf(t){return Number.isFinite(t)?(Math.round(t/90)%4+4)%4:0}export function isSideways(t){return t%2==1}export function poseStyle(t,e){const o="horizontal"===e||"both"===e,n="vertical"===e||"both"===e;if(0===t&&!o&&!n)return null;const[i,r]=isSideways(t)?[n,o]:[o,n];return{scale:i||r?`${i?-1:1} ${r?-1:1}`:void 0,rotate:0===t?void 0:90*t+"deg",...isSideways(t)?{position:"absolute",top:"50%",left:"50%",width:"100cqh",height:"100cqw",maxWidth:"none",translate:"-50% -50%"}:null}}export function layerStyle(t,e,o){const grown=t=>0===o?t:`calc(${t} + ${2*o}px)`;return isSideways(t)?{...poseStyle(t,e),width:grown("100cqh"),height:grown("100cqw")}:{...poseStyle(t,e),position:"absolute",top:-o+"px",left:-o+"px",width:grown("100%"),height:grown("100%"),maxWidth:"none"}}export function positionFractions(t){const e=[.5,.5],o=t.trim().toLowerCase().split(/\s+/);for(let t=0;t<o.length;t+=1){const n=["left","top","right","bottom"].indexOf(o[t]);if(n>=0)e[n%2]=n>1?1:0;else if(/^-?\d*\.?\d+%$/.test(o[t]))e[0===t?0:1]=parseFloat(o[t])/100;else if("center"!==o[t])return null}return e}export function elementFractions([t,e],o,n,i){let r=n?1-t:t,s=i?1-e:e;for(let t=0;t<o;t+=1)[r,s]=[s,1-r];return[r,s]}export function objectPosition(t,e,o){const n=positionFractions(t);if(null===n)return t;const[i,r]=elementFractions(n,e,"horizontal"===o||"both"===o,"vertical"===o||"both"===o),percent=t=>Math.round(1e4*t)/100+"%";return`${percent(i)} ${percent(r)}`}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The value `inert` has to be written with for a given React to put it in the
3
+ * DOM.
4
+ *
5
+ * React 19 knows `inert` as a boolean attribute, writes `true` and drops an
6
+ * empty string. React 18 does not know it at all: it drops `true` with a warning
7
+ * and writes a string as it is. A dropped attribute leaves the subtree
8
+ * focusable and on the accessibility tree, which is exactly what the attribute
9
+ * was there to stop, and nothing on the page looks any different.
10
+ */
11
+ export declare function inertValueFor(version: string): true | '';
12
+ /**
13
+ * `inert` as props to spread onto an element, written the way the running React
14
+ * keeps it. Nothing at all when the element is not inert, so the attribute is
15
+ * absent rather than present and false.
16
+ */
17
+ export declare function inertProps(inert: boolean): {
18
+ inert?: boolean;
19
+ };
@@ -0,0 +1 @@
1
+ import*as r from"react";export function inertValueFor(r){return Number.parseInt(r,10)>=19||""}const e=inertValueFor(r.version);export function inertProps(r){return r?{inert:e}:{}}